From f1406d4eec8fc6c614d02aaee5609c27025bf335 Mon Sep 17 00:00:00 2001 From: Moe Date: Thu, 7 Jun 2018 23:21:38 -0700 Subject: [PATCH] Shinobi CE officially lands on Gitlab --- .gitignore | 12 + .npmignore | 2 + COPYING | 674 + INSTALL/.gitignore | 1 + INSTALL/README.md | 17 + INSTALL/autoinstall-ubuntu-latest.sh | 5 + INSTALL/autoinstall-ubuntu-stable.sh | 5 + INSTALL/centos.sh | 188 + INSTALL/cuda4-part1.sh | 15 + INSTALL/cuda9-part1.sh | 15 + INSTALL/cuda9-part2-after-reboot.sh | 2 + INSTALL/ffmpeg.sh | 22 + INSTALL/freebsd.sh | 73 + INSTALL/installDatabase.js | 37 + INSTALL/macos-part2.sh | 90 + INSTALL/macos.sh | 50 + INSTALL/now.sh | 33 + INSTALL/openalpr-gpu-easy.sh | 31 + INSTALL/openalpr-opencl.sh | 3 + INSTALL/opencv-cuda.sh | 101 + INSTALL/shinobi | 10 + INSTALL/shinobi.service | 11 + INSTALL/start.sh | 9 + INSTALL/ubuntu-easyinstall.sh | 175 + INSTALL/ubuntu.sh | 202 + LICENSE | 674 + README.md | 146 + UPDATE.sh | 24 + camera.js | 6795 ++++++++ conf.sample.json | 28 + cron.js | 518 + definitions/en_CA.json | 1192 ++ languages/ar.json | 497 + languages/bn.json | 496 + languages/de.json | 497 + languages/en_CA.json | 695 + languages/fr.json | 666 + languages/ja.json | 496 + languages/pt_BR.json | 531 + languages/ru.json | 496 + languages/zh.json | 496 + package.json | 44 + plugins/.gitignore | 4 + plugins/child/.gitignore | 3 + plugins/child/child.js | 392 + plugins/child/conf.sample.json | 6 + plugins/darknet/INSTALL.sh | 13 + plugins/darknet/conf.sample.json | 9 + plugins/darknet/modifiedMakefile | 119 + plugins/darknet/shinobi-darknet.js | 456 + plugins/microsoft/conf.sample.json | 29 + plugins/microsoft/shinobi-ms-vision.js | 170 + plugins/motion/.gitignore | 1 + plugins/motion/INSTALL.sh | 5 + plugins/motion/README.md | 56 + plugins/motion/conf.sample.json | 7 + plugins/motion/libs/clusterPoints.js | 115 + plugins/motion/shinobi-motion-pixel.js | 245 + plugins/motion/shinobi-motion.js | 233 + plugins/openalpr/.gitignore | 2 + plugins/openalpr/README.md | 93 + plugins/openalpr/conf.sample.json | 9 + plugins/openalpr/openalpr.conf | 94 + plugins/openalpr/package.json | 18 + plugins/openalpr/shinobi-openalpr.js | 413 + plugins/opencv/INSTALL.sh | 15 + plugins/opencv/conf.sample.json | 9 + plugins/opencv/openalpr.conf | 94 + plugins/opencv/shinobi-opencv.js | 465 + sql/.gitignore | 2 + sql/default_data.sql | 20 + sql/docker/01-framework.sql | 113 + sql/framework.sql | 107 + sql/mssql/default_data.sql | 20 + sql/mssql/framework.sql | 107 + sql/mssql/user.sql | 3 + sql/postgresql/default_data.sql | 20 + sql/postgresql/framework.sql | 107 + sql/postgresql/user.sql | 3 + sql/shinobi.sample.sqlite | Bin 0 -> 40960 bytes sql/sqllog.txt | 1 + sql/tables.sql | 84 + sql/update-1-1-2017.sql | 11 + sql/update-13-7-2017.sql | 2 + sql/update-17-5-2017.sql | 17 + sql/update-2-2-2017.sql | 28 + sql/update-26-08-2017.sql | 2 + sql/update-5-6-2017.sql | 3 + sql/user.sql | 3 + super.sample.json | 6 + tools/FLV Stream/ffmpegToWeb.js | 102 + tools/FLV Stream/flv.min.js | 7 + tools/FLV Stream/flv.min.js.map | 1 + tools/FLV Stream/index.html | 36 + tools/MP4 Stream/ffmpegToWeb.js | 95 + tools/MP4 Stream/flv.min.js | 7 + tools/MP4 Stream/flv.min.js.map | 1 + tools/MP4 Stream/index.html | 29 + tools/addVideos.js.disabled | 48 + tools/checkNPM.js | 10 + tools/coco/testCoco.js | 103 + tools/cron.js | 405 + tools/ffmpegToWeb.rar | Bin 0 -> 309545 bytes tools/ffmpegToWeb/.gitignore | 9 + tools/ffmpegToWeb/Player/broadway/.gitignore | 3 + tools/ffmpegToWeb/Player/broadway/.npmignore | 4 + tools/ffmpegToWeb/Player/broadway/AUTHORS | 19 + tools/ffmpegToWeb/Player/broadway/LICENSE | 10 + tools/ffmpegToWeb/Player/broadway/README.md | 11 + .../Player/broadway/broadway/Decoder.js | 966 ++ .../broadway/canvas/FilterWebGLCanvas.js | 71 + .../Player/broadway/canvas/Program.js | 32 + .../Player/broadway/canvas/README.md | 4 + .../Player/broadway/canvas/Script.js | 41 + .../Player/broadway/canvas/Shader.js | 38 + .../Player/broadway/canvas/Texture.js | 47 + .../Player/broadway/canvas/WebGLCanvas.js | 261 + .../Player/broadway/canvas/YUVCanvas.js | 51 + .../Player/broadway/canvas/YUVWebGLCanvas.js | 108 + .../Player/broadway/dist/http-live-player.js | 5214 +++++++ .../h264liveplayer/http-live-player.js | 5186 +++++++ .../ffmpegToWeb/Player/broadway/package.json | 35 + .../ffmpegToWeb/Player/broadway/utils/Size.js | 23 + .../Player/broadway/utils/assert.js | 12 + .../Player/broadway/utils/error.js | 8 + .../Player/broadway/utils/glUtils.js | 117 + .../Player/broadway/utils/inherit.js | 17 + .../Player/broadway/wsavc/index.js | 159 + tools/ffmpegToWeb/eventemitter.js | 69 + tools/ffmpegToWeb/ffmpegToWeb.js | 117 + tools/ffmpegToWeb/index.html | 45 + tools/ffmpegToWeb/package.json | 15 + tools/getGitLog.js | 2 + tools/getVersionFromGit.js | 23 + tools/httpHookTest.js | 23 + tools/matchFeaturesTest/PeopleCounterMain.js | 109 + tools/matchFeaturesTest/findwaldo.jpg | Bin 0 -> 570797 bytes tools/matchFeaturesTest/matchFeaturesTest.js | 98 + tools/matchFeaturesTest/waldo.jpg | Bin 0 -> 1280 bytes tools/modifyConfiguration.js | 30 + tools/sql2mongo/mesh.js | 2342 +++ tools/sql2mongo/sql2mongo.js | 352 + tools/translateDefinitionFile.js | 84 + tools/translateLanguageFile.js | 84 + web/libs/.gitignore | 1 + web/libs/audio/alert.mp3 | Bin 0 -> 13744 bytes web/libs/audio/pop.mp3 | Bin 0 -> 1704 bytes web/libs/css/bootstrap-table.min.css | 1 + web/libs/css/bootstrap-theme.css | 587 + web/libs/css/bootstrap-theme.css.map | 1 + web/libs/css/bootstrap-theme.min.css | 6 + web/libs/css/bootstrap-theme.min.css.map | 1 + web/libs/css/bootstrap.css | 6757 ++++++++ web/libs/css/bootstrap.css.map | 1 + web/libs/css/bootstrap.min.css | 6 + web/libs/css/bootstrap.min.css.map | 1 + web/libs/css/c3.css | 174 + web/libs/css/circles.css | 463 + web/libs/css/daterangepicker.css | 269 + web/libs/css/daterangepicker.scss | 611 + web/libs/css/font-awesome.css | 2337 +++ web/libs/css/font-awesome.min.css | 4 + web/libs/css/fullcalendar.min.css | 5 + web/libs/css/fullcalendar.print.css | 208 + web/libs/css/gridstack-extra.min.css | 1 + web/libs/css/gridstack.min.css | 1 + web/libs/css/login.css | 105 + web/libs/css/main.dash2.css | 716 + web/libs/css/material.min.css | 9 + web/libs/css/material.min.css.map | 1 + web/libs/css/material.style.css | 634 + web/libs/css/pnotify.custom.min.css | 1 + web/libs/css/poseidon.css | 246 + web/libs/css/vbox.css | 1233 ++ web/libs/fonts/FontAwesome.otf | Bin 0 -> 134808 bytes web/libs/fonts/fontawesome-webfont.eot | Bin 0 -> 165742 bytes web/libs/fonts/fontawesome-webfont.svg | 2671 ++++ web/libs/fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes web/libs/fonts/fontawesome-webfont.woff | Bin 0 -> 98024 bytes web/libs/fonts/fontawesome-webfont.woff2 | Bin 0 -> 77160 bytes web/libs/img/bg.jpg | Bin 0 -> 4652 bytes web/libs/img/demo.jpg | Bin 0 -> 216462 bytes web/libs/img/icon/README.md | 7 + .../img/icon/apple-touch-icon-114x114.png | Bin 0 -> 18584 bytes .../img/icon/apple-touch-icon-120x120.png | Bin 0 -> 20173 bytes .../img/icon/apple-touch-icon-144x144.png | Bin 0 -> 26056 bytes .../img/icon/apple-touch-icon-152x152.png | Bin 0 -> 30296 bytes web/libs/img/icon/apple-touch-icon-57x57.png | Bin 0 -> 6286 bytes web/libs/img/icon/apple-touch-icon-60x60.png | Bin 0 -> 6836 bytes web/libs/img/icon/apple-touch-icon-72x72.png | Bin 0 -> 9043 bytes web/libs/img/icon/apple-touch-icon-76x76.png | Bin 0 -> 10144 bytes web/libs/img/icon/circle-text.png | Bin 0 -> 227643 bytes web/libs/img/icon/favicon-128.png | Bin 0 -> 19058 bytes web/libs/img/icon/favicon-16x16.png | Bin 0 -> 852 bytes web/libs/img/icon/favicon-196x196.png | Bin 0 -> 45989 bytes web/libs/img/icon/favicon-32x32.png | Bin 0 -> 2420 bytes web/libs/img/icon/favicon-96x96.png | Bin 0 -> 12614 bytes web/libs/img/icon/favicon.ico | Bin 0 -> 34494 bytes web/libs/img/icon/mstile-144x144.png | Bin 0 -> 26056 bytes web/libs/img/icon/mstile-150x150.png | Bin 0 -> 76096 bytes web/libs/img/icon/mstile-310x150.png | Bin 0 -> 154259 bytes web/libs/img/icon/mstile-310x310-circle.png | Bin 0 -> 223496 bytes web/libs/img/icon/mstile-310x310.png | Bin 0 -> 273135 bytes web/libs/img/icon/mstile-70x70.png | Bin 0 -> 19058 bytes web/libs/js/Chart.js | 12757 ++++++++++++++++ web/libs/js/bootstrap-table-locale-all.min.js | 7 + web/libs/js/bootstrap-table.min.js | 8 + web/libs/js/bootstrap.js | 2377 +++ web/libs/js/bootstrap.min.js | 7 + web/libs/js/c3.js | 9236 +++++++++++ web/libs/js/clock.js | 26 + web/libs/js/clusterPoints.js | 119 + web/libs/js/d3.v3.min.js | 5 + web/libs/js/dash.mediaplayer.min.js | 28 + web/libs/js/daterangepicker.js | 1627 ++ web/libs/js/flv.min.js | 7 + web/libs/js/flv.min.js.map | 1 + web/libs/js/flv.shinobi.js | 6280 ++++++++ web/libs/js/fullcalendar.min.js | 9 + web/libs/js/gcal.js | 180 + web/libs/js/gridstack.jQueryUI.min.js | 9 + web/libs/js/gridstack.min.js | 10 + web/libs/js/gridstack.min.map | 1 + web/libs/js/hls.min.js | 7 + web/libs/js/jquery-ui.min.js | 8 + web/libs/js/jquery.canvasAreaDraw.js | 263 + web/libs/js/jquery.min.js | 6 + web/libs/js/jquery.serialize.js | 1 + web/libs/js/livestamp.min.js | 4 + web/libs/js/locale-all.js | 5 + web/libs/js/lodash.min.js | 89 + web/libs/js/main.dash2.js | 5346 +++++++ web/libs/js/material.min.js | 10 + web/libs/js/material.min.js.map | 1 + web/libs/js/menu.js | 17 + web/libs/js/moment.js | 4195 +++++ web/libs/js/morris.min.js | 7 + web/libs/js/npm.js | 13 + web/libs/js/placeholder.js | 2 + web/libs/js/pnotify.custom.min.js | 67 + web/libs/js/poseidon.js | 608 + web/libs/js/socket.io.js | 7685 ++++++++++ web/libs/less/animated.less | 34 + web/libs/less/bordered-pulled.less | 25 + web/libs/less/core.less | 12 + web/libs/less/fixed-width.less | 6 + web/libs/less/font-awesome.less | 18 + web/libs/less/icons.less | 789 + web/libs/less/larger.less | 13 + web/libs/less/list.less | 19 + web/libs/less/mixins.less | 60 + web/libs/less/path.less | 15 + web/libs/less/rotated-flipped.less | 20 + web/libs/less/screen-reader.less | 5 + web/libs/less/stacked.less | 20 + web/libs/less/variables.less | 800 + web/libs/scss/_animated.scss | 34 + web/libs/scss/_bordered-pulled.scss | 25 + web/libs/scss/_core.scss | 12 + web/libs/scss/_fixed-width.scss | 6 + web/libs/scss/_icons.scss | 789 + web/libs/scss/_larger.scss | 13 + web/libs/scss/_list.scss | 19 + web/libs/scss/_mixins.scss | 60 + web/libs/scss/_path.scss | 15 + web/libs/scss/_rotated-flipped.scss | 20 + web/libs/scss/_screen-reader.scss | 5 + web/libs/scss/_stacked.scss | 20 + web/libs/scss/_variables.scss | 800 + web/libs/scss/font-awesome.scss | 18 + web/libs/themes/Enterprise Blue/style.css | 41 + web/pages/admin.ejs | 239 + web/pages/blocks/api.ejs | 95 + web/pages/blocks/confirm.ejs | 37 + web/pages/blocks/filters.ejs | 118 + web/pages/blocks/header.ejs | 36 + web/pages/blocks/help.ejs | 45 + web/pages/blocks/logs.ejs | 37 + web/pages/blocks/mainpermissions.ejs | 219 + web/pages/blocks/migrator.ejs | 81 + web/pages/blocks/monitoredit.ejs | 1475 ++ web/pages/blocks/multimon.ejs | 148 + web/pages/blocks/powervideo.ejs | 86 + web/pages/blocks/probe.ejs | 94 + web/pages/blocks/region.ejs | 67 + web/pages/blocks/settings.ejs | 282 + web/pages/blocks/subpermissions.ejs | 105 + web/pages/blocks/timelapse.ejs | 80 + web/pages/blocks/videoview.ejs | 69 + web/pages/dashcam.ejs | 268 + web/pages/embed.ejs | 413 + web/pages/factor.ejs | 69 + web/pages/grid.ejs | 117 + web/pages/home.ejs | 206 + web/pages/index.ejs | 142 + web/pages/mjpeg.ejs | 5 + web/pages/script.ejs | 1 + web/pages/streamer.ejs | 143 + web/pages/super.ejs | 300 + web/templates/boilerplate/README.md | 58 + .../boilerplate/assets/css/bootstrap.min.css | 7 + .../assets/css/now-ui-dashboard.css | 3570 +++++ .../assets/css/now-ui-dashboard.css.map | 1 + .../assets/css/now-ui-dashboard.min.css | 24 + .../boilerplate/assets/css/styles.css | 51 + .../fonts/Montserrat/Montserrat-Black.eot | Bin 0 -> 102451 bytes .../fonts/Montserrat/Montserrat-Black.woff | Bin 0 -> 107388 bytes .../fonts/Montserrat/Montserrat-Black.woff2 | Bin 0 -> 82528 bytes .../Montserrat/Montserrat-BlackItalic.eot | Bin 0 -> 107248 bytes .../Montserrat/Montserrat-BlackItalic.woff | Bin 0 -> 112068 bytes .../Montserrat/Montserrat-BlackItalic.woff2 | Bin 0 -> 85576 bytes .../fonts/Montserrat/Montserrat-Bold.eot | Bin 0 -> 104070 bytes .../fonts/Montserrat/Montserrat-Bold.woff | Bin 0 -> 108200 bytes .../fonts/Montserrat/Montserrat-Bold.woff2 | Bin 0 -> 83392 bytes .../Montserrat/Montserrat-BoldItalic.eot | Bin 0 -> 109016 bytes .../Montserrat/Montserrat-BoldItalic.woff | Bin 0 -> 113132 bytes .../Montserrat/Montserrat-BoldItalic.woff2 | Bin 0 -> 86440 bytes .../fonts/Montserrat/Montserrat-ExtraBold.eot | Bin 0 -> 103434 bytes .../Montserrat/Montserrat-ExtraBold.woff | Bin 0 -> 107912 bytes .../Montserrat/Montserrat-ExtraBold.woff2 | Bin 0 -> 82888 bytes .../Montserrat/Montserrat-ExtraBoldItalic.eot | Bin 0 -> 108428 bytes .../Montserrat-ExtraBoldItalic.woff | Bin 0 -> 112880 bytes .../Montserrat-ExtraBoldItalic.woff2 | Bin 0 -> 86192 bytes .../Montserrat/Montserrat-ExtraLight.eot | Bin 0 -> 102071 bytes .../Montserrat/Montserrat-ExtraLight.woff | Bin 0 -> 106308 bytes .../Montserrat/Montserrat-ExtraLight.woff2 | Bin 0 -> 81828 bytes .../Montserrat-ExtraLightItalic.eot | Bin 0 -> 106113 bytes .../Montserrat-ExtraLightItalic.woff | Bin 0 -> 110692 bytes .../Montserrat-ExtraLightItalic.woff2 | Bin 0 -> 84508 bytes .../fonts/Montserrat/Montserrat-Italic.eot | Bin 0 -> 107752 bytes .../fonts/Montserrat/Montserrat-Italic.woff | Bin 0 -> 112300 bytes .../fonts/Montserrat/Montserrat-Italic.woff2 | Bin 0 -> 86024 bytes .../fonts/Montserrat/Montserrat-Light.eot | Bin 0 -> 103001 bytes .../fonts/Montserrat/Montserrat-Light.woff | Bin 0 -> 106924 bytes .../fonts/Montserrat/Montserrat-Light.woff2 | Bin 0 -> 82104 bytes .../Montserrat/Montserrat-LightItalic.eot | Bin 0 -> 107149 bytes .../Montserrat/Montserrat-LightItalic.woff | Bin 0 -> 111468 bytes .../Montserrat/Montserrat-LightItalic.woff2 | Bin 0 -> 85172 bytes .../fonts/Montserrat/Montserrat-Medium.eot | Bin 0 -> 104101 bytes .../fonts/Montserrat/Montserrat-Medium.woff | Bin 0 -> 107872 bytes .../fonts/Montserrat/Montserrat-Medium.woff2 | Bin 0 -> 83080 bytes .../Montserrat/Montserrat-MediumItalic.eot | Bin 0 -> 108677 bytes .../Montserrat/Montserrat-MediumItalic.woff | Bin 0 -> 112476 bytes .../Montserrat/Montserrat-MediumItalic.woff2 | Bin 0 -> 86468 bytes .../fonts/Montserrat/Montserrat-Regular.eot | Bin 0 -> 104215 bytes .../fonts/Montserrat/Montserrat-Regular.woff | Bin 0 -> 108124 bytes .../fonts/Montserrat/Montserrat-Regular.woff2 | Bin 0 -> 83532 bytes .../fonts/Montserrat/Montserrat-SemiBold.eot | Bin 0 -> 103341 bytes .../fonts/Montserrat/Montserrat-SemiBold.woff | Bin 0 -> 107524 bytes .../Montserrat/Montserrat-SemiBold.woff2 | Bin 0 -> 82620 bytes .../Montserrat/Montserrat-SemiBoldItalic.eot | Bin 0 -> 108290 bytes .../Montserrat/Montserrat-SemiBoldItalic.woff | Bin 0 -> 112440 bytes .../Montserrat-SemiBoldItalic.woff2 | Bin 0 -> 85980 bytes .../fonts/Montserrat/Montserrat-Thin.eot | Bin 0 -> 97905 bytes .../fonts/Montserrat/Montserrat-Thin.woff | Bin 0 -> 102452 bytes .../fonts/Montserrat/Montserrat-Thin.woff2 | Bin 0 -> 78392 bytes .../Montserrat/Montserrat-ThinItalic.eot | Bin 0 -> 101456 bytes .../Montserrat/Montserrat-ThinItalic.woff | Bin 0 -> 106400 bytes .../Montserrat/Montserrat-ThinItalic.woff2 | Bin 0 -> 80832 bytes .../assets/fonts/Montserrat/Montserrat.css | 399 + .../Montserrat/MontserratAlternates-Black.eot | Bin 0 -> 85264 bytes .../MontserratAlternates-Black.woff | Bin 0 -> 88280 bytes .../MontserratAlternates-Black.woff2 | Bin 0 -> 69140 bytes .../MontserratAlternates-BlackItalic.eot | Bin 0 -> 89463 bytes .../MontserratAlternates-BlackItalic.woff | Bin 0 -> 92568 bytes .../MontserratAlternates-BlackItalic.woff2 | Bin 0 -> 72368 bytes .../Montserrat/MontserratAlternates-Bold.eot | Bin 0 -> 87123 bytes .../Montserrat/MontserratAlternates-Bold.woff | Bin 0 -> 89816 bytes .../MontserratAlternates-Bold.woff2 | Bin 0 -> 70232 bytes .../MontserratAlternates-BoldItalic.eot | Bin 0 -> 90903 bytes .../MontserratAlternates-BoldItalic.woff | Bin 0 -> 93464 bytes .../MontserratAlternates-BoldItalic.woff2 | Bin 0 -> 73132 bytes .../MontserratAlternates-ExtraBold.eot | Bin 0 -> 87183 bytes .../MontserratAlternates-ExtraBold.woff | Bin 0 -> 89740 bytes .../MontserratAlternates-ExtraBold.woff2 | Bin 0 -> 70464 bytes .../MontserratAlternates-ExtraBoldItalic.eot | Bin 0 -> 90760 bytes .../MontserratAlternates-ExtraBoldItalic.woff | Bin 0 -> 93448 bytes ...MontserratAlternates-ExtraBoldItalic.woff2 | Bin 0 -> 72976 bytes .../MontserratAlternates-ExtraLight.eot | Bin 0 -> 85845 bytes .../MontserratAlternates-ExtraLight.woff | Bin 0 -> 88364 bytes .../MontserratAlternates-ExtraLight.woff2 | Bin 0 -> 69172 bytes .../MontserratAlternates-ExtraLightItalic.eot | Bin 0 -> 88968 bytes ...MontserratAlternates-ExtraLightItalic.woff | Bin 0 -> 91780 bytes ...ontserratAlternates-ExtraLightItalic.woff2 | Bin 0 -> 71648 bytes .../MontserratAlternates-Italic.eot | Bin 0 -> 90178 bytes .../MontserratAlternates-Italic.woff | Bin 0 -> 92968 bytes .../MontserratAlternates-Italic.woff2 | Bin 0 -> 72940 bytes .../Montserrat/MontserratAlternates-Light.eot | Bin 0 -> 86343 bytes .../MontserratAlternates-Light.woff | Bin 0 -> 88884 bytes .../MontserratAlternates-Light.woff2 | Bin 0 -> 69728 bytes .../MontserratAlternates-LightItalic.eot | Bin 0 -> 89428 bytes .../MontserratAlternates-LightItalic.woff | Bin 0 -> 92448 bytes .../MontserratAlternates-LightItalic.woff2 | Bin 0 -> 72068 bytes .../MontserratAlternates-Medium.eot | Bin 0 -> 87027 bytes .../MontserratAlternates-Medium.woff | Bin 0 -> 89664 bytes .../MontserratAlternates-Medium.woff2 | Bin 0 -> 70148 bytes .../MontserratAlternates-MediumItalic.eot | Bin 0 -> 90639 bytes .../MontserratAlternates-MediumItalic.woff | Bin 0 -> 93188 bytes .../MontserratAlternates-MediumItalic.woff2 | Bin 0 -> 73040 bytes .../MontserratAlternates-Regular.eot | Bin 0 -> 87088 bytes .../MontserratAlternates-Regular.woff | Bin 0 -> 89720 bytes .../MontserratAlternates-Regular.woff2 | Bin 0 -> 70316 bytes .../MontserratAlternates-SemiBold.eot | Bin 0 -> 86796 bytes .../MontserratAlternates-SemiBold.woff | Bin 0 -> 89264 bytes .../MontserratAlternates-SemiBold.woff2 | Bin 0 -> 69948 bytes .../MontserratAlternates-SemiBoldItalic.eot | Bin 0 -> 90411 bytes .../MontserratAlternates-SemiBoldItalic.woff | Bin 0 -> 92804 bytes .../MontserratAlternates-SemiBoldItalic.woff2 | Bin 0 -> 72488 bytes .../Montserrat/MontserratAlternates-Thin.eot | Bin 0 -> 82212 bytes .../Montserrat/MontserratAlternates-Thin.woff | Bin 0 -> 85048 bytes .../MontserratAlternates-Thin.woff2 | Bin 0 -> 66452 bytes .../MontserratAlternates-ThinItalic.eot | Bin 0 -> 84883 bytes .../MontserratAlternates-ThinItalic.woff | Bin 0 -> 88068 bytes .../MontserratAlternates-ThinItalic.woff2 | Bin 0 -> 68236 bytes .../assets/fonts/nucleo-outline.eot | Bin 0 -> 30528 bytes .../assets/fonts/nucleo-outline.ttf | Bin 0 -> 30352 bytes .../assets/fonts/nucleo-outline.woff | Bin 0 -> 18056 bytes .../assets/fonts/nucleo-outline.woff2 | Bin 0 -> 15364 bytes .../boilerplate/assets/js/bootstrap-notify.js | 433 + .../boilerplate/assets/js/bootstrap.min.js | 6 + .../boilerplate/assets/js/chartjs.min.js | 10 + web/templates/boilerplate/assets/js/main.js | 105 + .../boilerplate/assets/js/moment.min.js | 1 + .../assets/js/now-ui-dashboard.min.js | 1 + .../assets/js/perfect-scrollbar.jquery.min.js | 2 + .../boilerplate/assets/js/popper.min.js | 4 + web/templates/boilerplate/handler.js | 8 + .../boilerplate/views/blocks/footer.ejs | 23 + .../boilerplate/views/blocks/header.ejs | 48 + .../boilerplate/views/blocks/home.ejs | 132 + web/templates/boilerplate/views/index.ejs | 7 + 431 files changed, 118157 insertions(+) create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 COPYING create mode 100644 INSTALL/.gitignore create mode 100644 INSTALL/README.md create mode 100644 INSTALL/autoinstall-ubuntu-latest.sh create mode 100644 INSTALL/autoinstall-ubuntu-stable.sh create mode 100644 INSTALL/centos.sh create mode 100644 INSTALL/cuda4-part1.sh create mode 100644 INSTALL/cuda9-part1.sh create mode 100644 INSTALL/cuda9-part2-after-reboot.sh create mode 100644 INSTALL/ffmpeg.sh create mode 100644 INSTALL/freebsd.sh create mode 100644 INSTALL/installDatabase.js create mode 100644 INSTALL/macos-part2.sh create mode 100644 INSTALL/macos.sh create mode 100644 INSTALL/now.sh create mode 100644 INSTALL/openalpr-gpu-easy.sh create mode 100644 INSTALL/openalpr-opencl.sh create mode 100644 INSTALL/opencv-cuda.sh create mode 100644 INSTALL/shinobi create mode 100644 INSTALL/shinobi.service create mode 100644 INSTALL/start.sh create mode 100644 INSTALL/ubuntu-easyinstall.sh create mode 100644 INSTALL/ubuntu.sh create mode 100644 LICENSE create mode 100644 README.md create mode 100644 UPDATE.sh create mode 100644 camera.js create mode 100644 conf.sample.json create mode 100644 cron.js create mode 100644 definitions/en_CA.json create mode 100644 languages/ar.json create mode 100644 languages/bn.json create mode 100644 languages/de.json create mode 100644 languages/en_CA.json create mode 100644 languages/fr.json create mode 100644 languages/ja.json create mode 100644 languages/pt_BR.json create mode 100644 languages/ru.json create mode 100644 languages/zh.json create mode 100644 package.json create mode 100644 plugins/.gitignore create mode 100644 plugins/child/.gitignore create mode 100644 plugins/child/child.js create mode 100644 plugins/child/conf.sample.json create mode 100644 plugins/darknet/INSTALL.sh create mode 100644 plugins/darknet/conf.sample.json create mode 100644 plugins/darknet/modifiedMakefile create mode 100644 plugins/darknet/shinobi-darknet.js create mode 100644 plugins/microsoft/conf.sample.json create mode 100644 plugins/microsoft/shinobi-ms-vision.js create mode 100644 plugins/motion/.gitignore create mode 100644 plugins/motion/INSTALL.sh create mode 100644 plugins/motion/README.md create mode 100644 plugins/motion/conf.sample.json create mode 100644 plugins/motion/libs/clusterPoints.js create mode 100644 plugins/motion/shinobi-motion-pixel.js create mode 100644 plugins/motion/shinobi-motion.js create mode 100644 plugins/openalpr/.gitignore create mode 100644 plugins/openalpr/README.md create mode 100644 plugins/openalpr/conf.sample.json create mode 100644 plugins/openalpr/openalpr.conf create mode 100644 plugins/openalpr/package.json create mode 100644 plugins/openalpr/shinobi-openalpr.js create mode 100644 plugins/opencv/INSTALL.sh create mode 100644 plugins/opencv/conf.sample.json create mode 100644 plugins/opencv/openalpr.conf create mode 100644 plugins/opencv/shinobi-opencv.js create mode 100644 sql/.gitignore create mode 100644 sql/default_data.sql create mode 100644 sql/docker/01-framework.sql create mode 100644 sql/framework.sql create mode 100644 sql/mssql/default_data.sql create mode 100644 sql/mssql/framework.sql create mode 100644 sql/mssql/user.sql create mode 100644 sql/postgresql/default_data.sql create mode 100644 sql/postgresql/framework.sql create mode 100644 sql/postgresql/user.sql create mode 100644 sql/shinobi.sample.sqlite create mode 100644 sql/sqllog.txt create mode 100644 sql/tables.sql create mode 100644 sql/update-1-1-2017.sql create mode 100644 sql/update-13-7-2017.sql create mode 100644 sql/update-17-5-2017.sql create mode 100644 sql/update-2-2-2017.sql create mode 100644 sql/update-26-08-2017.sql create mode 100644 sql/update-5-6-2017.sql create mode 100644 sql/user.sql create mode 100644 super.sample.json create mode 100644 tools/FLV Stream/ffmpegToWeb.js create mode 100644 tools/FLV Stream/flv.min.js create mode 100644 tools/FLV Stream/flv.min.js.map create mode 100644 tools/FLV Stream/index.html create mode 100644 tools/MP4 Stream/ffmpegToWeb.js create mode 100644 tools/MP4 Stream/flv.min.js create mode 100644 tools/MP4 Stream/flv.min.js.map create mode 100644 tools/MP4 Stream/index.html create mode 100644 tools/addVideos.js.disabled create mode 100644 tools/checkNPM.js create mode 100644 tools/coco/testCoco.js create mode 100644 tools/cron.js create mode 100644 tools/ffmpegToWeb.rar create mode 100644 tools/ffmpegToWeb/.gitignore create mode 100644 tools/ffmpegToWeb/Player/broadway/.gitignore create mode 100644 tools/ffmpegToWeb/Player/broadway/.npmignore create mode 100644 tools/ffmpegToWeb/Player/broadway/AUTHORS create mode 100644 tools/ffmpegToWeb/Player/broadway/LICENSE create mode 100644 tools/ffmpegToWeb/Player/broadway/README.md create mode 100644 tools/ffmpegToWeb/Player/broadway/broadway/Decoder.js create mode 100644 tools/ffmpegToWeb/Player/broadway/canvas/FilterWebGLCanvas.js create mode 100644 tools/ffmpegToWeb/Player/broadway/canvas/Program.js create mode 100644 tools/ffmpegToWeb/Player/broadway/canvas/README.md create mode 100644 tools/ffmpegToWeb/Player/broadway/canvas/Script.js create mode 100644 tools/ffmpegToWeb/Player/broadway/canvas/Shader.js create mode 100644 tools/ffmpegToWeb/Player/broadway/canvas/Texture.js create mode 100644 tools/ffmpegToWeb/Player/broadway/canvas/WebGLCanvas.js create mode 100644 tools/ffmpegToWeb/Player/broadway/canvas/YUVCanvas.js create mode 100644 tools/ffmpegToWeb/Player/broadway/canvas/YUVWebGLCanvas.js create mode 100644 tools/ffmpegToWeb/Player/broadway/dist/http-live-player.js create mode 100644 tools/ffmpegToWeb/Player/broadway/h264liveplayer/http-live-player.js create mode 100644 tools/ffmpegToWeb/Player/broadway/package.json create mode 100644 tools/ffmpegToWeb/Player/broadway/utils/Size.js create mode 100644 tools/ffmpegToWeb/Player/broadway/utils/assert.js create mode 100644 tools/ffmpegToWeb/Player/broadway/utils/error.js create mode 100644 tools/ffmpegToWeb/Player/broadway/utils/glUtils.js create mode 100644 tools/ffmpegToWeb/Player/broadway/utils/inherit.js create mode 100644 tools/ffmpegToWeb/Player/broadway/wsavc/index.js create mode 100644 tools/ffmpegToWeb/eventemitter.js create mode 100644 tools/ffmpegToWeb/ffmpegToWeb.js create mode 100644 tools/ffmpegToWeb/index.html create mode 100644 tools/ffmpegToWeb/package.json create mode 100644 tools/getGitLog.js create mode 100644 tools/getVersionFromGit.js create mode 100644 tools/httpHookTest.js create mode 100644 tools/matchFeaturesTest/PeopleCounterMain.js create mode 100644 tools/matchFeaturesTest/findwaldo.jpg create mode 100644 tools/matchFeaturesTest/matchFeaturesTest.js create mode 100644 tools/matchFeaturesTest/waldo.jpg create mode 100644 tools/modifyConfiguration.js create mode 100644 tools/sql2mongo/mesh.js create mode 100644 tools/sql2mongo/sql2mongo.js create mode 100644 tools/translateDefinitionFile.js create mode 100644 tools/translateLanguageFile.js create mode 100644 web/libs/.gitignore create mode 100644 web/libs/audio/alert.mp3 create mode 100644 web/libs/audio/pop.mp3 create mode 100644 web/libs/css/bootstrap-table.min.css create mode 100644 web/libs/css/bootstrap-theme.css create mode 100644 web/libs/css/bootstrap-theme.css.map create mode 100644 web/libs/css/bootstrap-theme.min.css create mode 100644 web/libs/css/bootstrap-theme.min.css.map create mode 100644 web/libs/css/bootstrap.css create mode 100644 web/libs/css/bootstrap.css.map create mode 100644 web/libs/css/bootstrap.min.css create mode 100644 web/libs/css/bootstrap.min.css.map create mode 100644 web/libs/css/c3.css create mode 100644 web/libs/css/circles.css create mode 100644 web/libs/css/daterangepicker.css create mode 100644 web/libs/css/daterangepicker.scss create mode 100644 web/libs/css/font-awesome.css create mode 100644 web/libs/css/font-awesome.min.css create mode 100644 web/libs/css/fullcalendar.min.css create mode 100644 web/libs/css/fullcalendar.print.css create mode 100644 web/libs/css/gridstack-extra.min.css create mode 100644 web/libs/css/gridstack.min.css create mode 100644 web/libs/css/login.css create mode 100644 web/libs/css/main.dash2.css create mode 100644 web/libs/css/material.min.css create mode 100644 web/libs/css/material.min.css.map create mode 100644 web/libs/css/material.style.css create mode 100644 web/libs/css/pnotify.custom.min.css create mode 100644 web/libs/css/poseidon.css create mode 100644 web/libs/css/vbox.css create mode 100644 web/libs/fonts/FontAwesome.otf create mode 100644 web/libs/fonts/fontawesome-webfont.eot create mode 100644 web/libs/fonts/fontawesome-webfont.svg create mode 100644 web/libs/fonts/fontawesome-webfont.ttf create mode 100644 web/libs/fonts/fontawesome-webfont.woff create mode 100644 web/libs/fonts/fontawesome-webfont.woff2 create mode 100644 web/libs/img/bg.jpg create mode 100644 web/libs/img/demo.jpg create mode 100644 web/libs/img/icon/README.md create mode 100644 web/libs/img/icon/apple-touch-icon-114x114.png create mode 100644 web/libs/img/icon/apple-touch-icon-120x120.png create mode 100644 web/libs/img/icon/apple-touch-icon-144x144.png create mode 100644 web/libs/img/icon/apple-touch-icon-152x152.png create mode 100644 web/libs/img/icon/apple-touch-icon-57x57.png create mode 100644 web/libs/img/icon/apple-touch-icon-60x60.png create mode 100644 web/libs/img/icon/apple-touch-icon-72x72.png create mode 100644 web/libs/img/icon/apple-touch-icon-76x76.png create mode 100644 web/libs/img/icon/circle-text.png create mode 100644 web/libs/img/icon/favicon-128.png create mode 100644 web/libs/img/icon/favicon-16x16.png create mode 100644 web/libs/img/icon/favicon-196x196.png create mode 100644 web/libs/img/icon/favicon-32x32.png create mode 100644 web/libs/img/icon/favicon-96x96.png create mode 100644 web/libs/img/icon/favicon.ico create mode 100644 web/libs/img/icon/mstile-144x144.png create mode 100644 web/libs/img/icon/mstile-150x150.png create mode 100644 web/libs/img/icon/mstile-310x150.png create mode 100644 web/libs/img/icon/mstile-310x310-circle.png create mode 100644 web/libs/img/icon/mstile-310x310.png create mode 100644 web/libs/img/icon/mstile-70x70.png create mode 100644 web/libs/js/Chart.js create mode 100644 web/libs/js/bootstrap-table-locale-all.min.js create mode 100644 web/libs/js/bootstrap-table.min.js create mode 100644 web/libs/js/bootstrap.js create mode 100644 web/libs/js/bootstrap.min.js create mode 100644 web/libs/js/c3.js create mode 100644 web/libs/js/clock.js create mode 100644 web/libs/js/clusterPoints.js create mode 100644 web/libs/js/d3.v3.min.js create mode 100644 web/libs/js/dash.mediaplayer.min.js create mode 100644 web/libs/js/daterangepicker.js create mode 100644 web/libs/js/flv.min.js create mode 100644 web/libs/js/flv.min.js.map create mode 100644 web/libs/js/flv.shinobi.js create mode 100644 web/libs/js/fullcalendar.min.js create mode 100644 web/libs/js/gcal.js create mode 100644 web/libs/js/gridstack.jQueryUI.min.js create mode 100644 web/libs/js/gridstack.min.js create mode 100644 web/libs/js/gridstack.min.map create mode 100644 web/libs/js/hls.min.js create mode 100644 web/libs/js/jquery-ui.min.js create mode 100644 web/libs/js/jquery.canvasAreaDraw.js create mode 100644 web/libs/js/jquery.min.js create mode 100644 web/libs/js/jquery.serialize.js create mode 100644 web/libs/js/livestamp.min.js create mode 100644 web/libs/js/locale-all.js create mode 100644 web/libs/js/lodash.min.js create mode 100644 web/libs/js/main.dash2.js create mode 100644 web/libs/js/material.min.js create mode 100644 web/libs/js/material.min.js.map create mode 100644 web/libs/js/menu.js create mode 100644 web/libs/js/moment.js create mode 100644 web/libs/js/morris.min.js create mode 100644 web/libs/js/npm.js create mode 100644 web/libs/js/placeholder.js create mode 100644 web/libs/js/pnotify.custom.min.js create mode 100644 web/libs/js/poseidon.js create mode 100644 web/libs/js/socket.io.js create mode 100644 web/libs/less/animated.less create mode 100644 web/libs/less/bordered-pulled.less create mode 100644 web/libs/less/core.less create mode 100644 web/libs/less/fixed-width.less create mode 100644 web/libs/less/font-awesome.less create mode 100644 web/libs/less/icons.less create mode 100644 web/libs/less/larger.less create mode 100644 web/libs/less/list.less create mode 100644 web/libs/less/mixins.less create mode 100644 web/libs/less/path.less create mode 100644 web/libs/less/rotated-flipped.less create mode 100644 web/libs/less/screen-reader.less create mode 100644 web/libs/less/stacked.less create mode 100644 web/libs/less/variables.less create mode 100644 web/libs/scss/_animated.scss create mode 100644 web/libs/scss/_bordered-pulled.scss create mode 100644 web/libs/scss/_core.scss create mode 100644 web/libs/scss/_fixed-width.scss create mode 100644 web/libs/scss/_icons.scss create mode 100644 web/libs/scss/_larger.scss create mode 100644 web/libs/scss/_list.scss create mode 100644 web/libs/scss/_mixins.scss create mode 100644 web/libs/scss/_path.scss create mode 100644 web/libs/scss/_rotated-flipped.scss create mode 100644 web/libs/scss/_screen-reader.scss create mode 100644 web/libs/scss/_stacked.scss create mode 100644 web/libs/scss/_variables.scss create mode 100644 web/libs/scss/font-awesome.scss create mode 100644 web/libs/themes/Enterprise Blue/style.css create mode 100644 web/pages/admin.ejs create mode 100644 web/pages/blocks/api.ejs create mode 100644 web/pages/blocks/confirm.ejs create mode 100644 web/pages/blocks/filters.ejs create mode 100644 web/pages/blocks/header.ejs create mode 100644 web/pages/blocks/help.ejs create mode 100644 web/pages/blocks/logs.ejs create mode 100644 web/pages/blocks/mainpermissions.ejs create mode 100644 web/pages/blocks/migrator.ejs create mode 100644 web/pages/blocks/monitoredit.ejs create mode 100644 web/pages/blocks/multimon.ejs create mode 100644 web/pages/blocks/powervideo.ejs create mode 100644 web/pages/blocks/probe.ejs create mode 100644 web/pages/blocks/region.ejs create mode 100644 web/pages/blocks/settings.ejs create mode 100644 web/pages/blocks/subpermissions.ejs create mode 100644 web/pages/blocks/timelapse.ejs create mode 100644 web/pages/blocks/videoview.ejs create mode 100644 web/pages/dashcam.ejs create mode 100644 web/pages/embed.ejs create mode 100644 web/pages/factor.ejs create mode 100644 web/pages/grid.ejs create mode 100644 web/pages/home.ejs create mode 100644 web/pages/index.ejs create mode 100644 web/pages/mjpeg.ejs create mode 100644 web/pages/script.ejs create mode 100644 web/pages/streamer.ejs create mode 100644 web/pages/super.ejs create mode 100644 web/templates/boilerplate/README.md create mode 100644 web/templates/boilerplate/assets/css/bootstrap.min.css create mode 100644 web/templates/boilerplate/assets/css/now-ui-dashboard.css create mode 100644 web/templates/boilerplate/assets/css/now-ui-dashboard.css.map create mode 100644 web/templates/boilerplate/assets/css/now-ui-dashboard.min.css create mode 100644 web/templates/boilerplate/assets/css/styles.css create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Black.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Black.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Black.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-BlackItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-BlackItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-BlackItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Bold.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Bold.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Bold.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-BoldItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-BoldItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-BoldItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ExtraBold.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ExtraBold.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ExtraBold.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ExtraBoldItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ExtraBoldItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ExtraBoldItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ExtraLight.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ExtraLight.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ExtraLight.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ExtraLightItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ExtraLightItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ExtraLightItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Italic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Italic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Italic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Light.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Light.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Light.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-LightItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-LightItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-LightItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Medium.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Medium.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Medium.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-MediumItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-MediumItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-MediumItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Regular.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Regular.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Regular.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-SemiBold.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-SemiBold.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-SemiBold.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-SemiBoldItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-SemiBoldItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-SemiBoldItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Thin.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Thin.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-Thin.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ThinItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ThinItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat-ThinItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/Montserrat.css create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Black.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Black.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Black.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-BlackItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-BlackItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-BlackItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Bold.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Bold.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Bold.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-BoldItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-BoldItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-BoldItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ExtraBold.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ExtraBold.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ExtraBold.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ExtraBoldItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ExtraBoldItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ExtraBoldItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ExtraLight.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ExtraLight.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ExtraLight.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ExtraLightItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ExtraLightItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ExtraLightItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Italic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Italic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Italic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Light.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Light.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Light.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-LightItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-LightItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-LightItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Medium.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Medium.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Medium.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-MediumItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-MediumItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-MediumItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Regular.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Regular.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Regular.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-SemiBold.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-SemiBold.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-SemiBold.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-SemiBoldItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-SemiBoldItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-SemiBoldItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Thin.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Thin.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-Thin.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ThinItalic.eot create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ThinItalic.woff create mode 100644 web/templates/boilerplate/assets/fonts/Montserrat/MontserratAlternates-ThinItalic.woff2 create mode 100644 web/templates/boilerplate/assets/fonts/nucleo-outline.eot create mode 100644 web/templates/boilerplate/assets/fonts/nucleo-outline.ttf create mode 100644 web/templates/boilerplate/assets/fonts/nucleo-outline.woff create mode 100644 web/templates/boilerplate/assets/fonts/nucleo-outline.woff2 create mode 100644 web/templates/boilerplate/assets/js/bootstrap-notify.js create mode 100644 web/templates/boilerplate/assets/js/bootstrap.min.js create mode 100644 web/templates/boilerplate/assets/js/chartjs.min.js create mode 100644 web/templates/boilerplate/assets/js/main.js create mode 100644 web/templates/boilerplate/assets/js/moment.min.js create mode 100644 web/templates/boilerplate/assets/js/now-ui-dashboard.min.js create mode 100644 web/templates/boilerplate/assets/js/perfect-scrollbar.jquery.min.js create mode 100644 web/templates/boilerplate/assets/js/popper.min.js create mode 100644 web/templates/boilerplate/handler.js create mode 100644 web/templates/boilerplate/views/blocks/footer.ejs create mode 100644 web/templates/boilerplate/views/blocks/header.ejs create mode 100644 web/templates/boilerplate/views/blocks/home.ejs create mode 100644 web/templates/boilerplate/views/index.ejs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..74b6b65 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules +videos +events +frames +web.old +.DS_Store +.vagrant +conf.json +super.json +dbdata +npm-debug.log +shinobi.sqlite \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..5af8981 --- /dev/null +++ b/.npmignore @@ -0,0 +1,2 @@ +node_modules +conf.json \ No newline at end of file diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..20d40b6 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/INSTALL/.gitignore b/INSTALL/.gitignore new file mode 100644 index 0000000..bc56e1f --- /dev/null +++ b/INSTALL/.gitignore @@ -0,0 +1 @@ +installed.txt \ No newline at end of file diff --git a/INSTALL/README.md b/INSTALL/README.md new file mode 100644 index 0000000..d59d017 --- /dev/null +++ b/INSTALL/README.md @@ -0,0 +1,17 @@ +#### Fast Install (The Ninja Way) + +1. Become `root` to use the installer and run Shinobi. Use one of the following to do so. + + - Ubuntu 17.04, 17.10 + - `sudo su` + - CentOS 7 + - `su` + - MacOS 10.7(+) + - `su` +2. Download and run the installer. + +``` +bash <(curl -s https://raw.githubusercontent.com/ShinobiCCTV/Shinobi-Installer/master/shinobi-install.sh) +``` + +More info can be found here. https://shinobi.video/docs/start \ No newline at end of file diff --git a/INSTALL/autoinstall-ubuntu-latest.sh b/INSTALL/autoinstall-ubuntu-latest.sh new file mode 100644 index 0000000..0ae4853 --- /dev/null +++ b/INSTALL/autoinstall-ubuntu-latest.sh @@ -0,0 +1,5 @@ +apt install git -y +git clone https://github.com/ShinobiCCTV/Shinobi.git -b dev Shinobi-dev +cd Shinobi-dev +chmod +x INSTALL/ubuntu-easyinstall.sh && INSTALL/ubuntu-easyinstall.sh +bash INSTALL/ubuntu-easyinstall.sh \ No newline at end of file diff --git a/INSTALL/autoinstall-ubuntu-stable.sh b/INSTALL/autoinstall-ubuntu-stable.sh new file mode 100644 index 0000000..6dc12bd --- /dev/null +++ b/INSTALL/autoinstall-ubuntu-stable.sh @@ -0,0 +1,5 @@ +apt install git -y +git clone https://github.com/ShinobiCCTV/Shinobi.git Shinobi +cd Shinobi +chmod +x INSTALL/ubuntu-easyinstall.sh && INSTALL/ubuntu-easyinstall.sh +bash INSTALL/ubuntu-easyinstall.sh \ No newline at end of file diff --git a/INSTALL/centos.sh b/INSTALL/centos.sh new file mode 100644 index 0000000..d122554 --- /dev/null +++ b/INSTALL/centos.sh @@ -0,0 +1,188 @@ +#!/bin/bash +echo "=========================================================" +echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!==" +echo "=========================================================" +echo "To answer yes type the letter (y) in lowercase and press ENTER." +echo "Default is no (N). Skip any components you already have or don't need." +echo "=============" +if [ ! -e "./conf.json" ]; then + cp conf.sample.json conf.json +fi +if [ ! -e "./super.json" ]; then + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + sudo cp super.sample.json super.json + echo "Shinobi - Do you want to enable superuser access?" + echo "This may be useful if passwords are forgotten or" + echo "if you would like to limit accessibility of an" + echo "account for business scenarios." + echo "(y)es or (N)o" + read createSuperJson + if [ "$createSuperJson" = "y" ] || [ "$createSuperJson" = "Y" ]; then + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + echo "* You can edit these settings in \"super.json\" located in the Shinobi directory." + sudo cp super.sample.json super.json + fi +fi +echo "Shinobi - Run yum update" +sudo yum update -y +echo "=============" +echo "Shinobi - Do you want to Install FFMPEG?" +echo "(y)es or (N)o" +read ffmpeginstall +if [ "$ffmpeginstall" = "y" ] || [ "$ffmpeginstall" = "Y" ]; then + echo "Shinobi - Do you want to Install FFMPEG with `apt` or download a static version provided with `npm`?" + echo "(a)pt or (N)pm" + echo "Press [ENTER] for default (npm)" + read ffmpegstaticinstall + if [ "$ffmpegstaticinstall" = "a" ] || [ "$ffmpegstaticinstall" = "A" ]; then + #Install EPEL Repo + sudo yum install epel-release -y + #Enable Nux Dextop repo for FFMPEG + sudo rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro + sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-1.el7.nux.noarch.rpm + sudo yum install ffmpeg ffmpeg-devel -y + else + sudo npm install ffmpeg-static + fi +fi +echo "Shinobi - Do you want to Install Node.js?" +echo "(y)es or (N)o" +read nodejsinstall +if [ "$nodejsinstall" = "y" ] || [ "$nodejsinstall" = "Y" ]; then + sudo wget https://rpm.nodesource.com/setup_8.x + sudo chmod +x setup_8.x + ./setup_8.x + sudo yum install nodejs -y +fi +echo "=============" +echo "Shinobi - Do you want to use MariaDB or SQLite3?" +echo "SQLite3 is better for small installs" +echo "MariaDB (MySQL) is better for large installs" +echo "(S)QLite3 or (M)ariaDB?" +echo "Press [ENTER] for default (MariaDB)" +read sqliteormariadb +if [ "$sqliteormariadb" = "S" ] || [ "$sqliteormariadb" = "s" ]; then + sudo npm install jsonfile + sudo yum install -y sqlite sqlite-devel -y + sudo npm install sqlite3 + node ./tools/modifyConfiguration.js databaseType=sqlite3 + if [ ! -e "./shinobi.sqlite" ]; then + echo "Creating shinobi.sqlite for SQLite3..." + sudo cp sql/shinobi.sample.sqlite shinobi.sqlite + else + echo "shinobi.sqlite already exists. Continuing..." + fi +else + echo "=============" + echo "Shinobi - Do you want to Install MariaDB?" + echo "(y)es or (N)o" + read mysqlagree + if [ "$mysqlagree" = "y" ] || [ "$mysqlagree" = "Y" ]; then + sudo yum install mariadb mariadb-server -y + #Start mysql and enable on boot + sudo systemctl start mariadb + sudo systemctl enable mariadb + #Run mysql install + sudo mysql_secure_installation + fi + echo "=============" + echo "Shinobi - Database Installation" + echo "(y)es or (N)o" + read mysqlagreeData + if [ "$mysqlagreeData" = "y" ] || [ "$mysqlagreeData" = "Y" ]; then + echo "What is your SQL Username?" + read sqluser + echo "What is your SQL Password?" + read sqlpass + sudo mysql -u $sqluser -p$sqlpass -e "source sql/user.sql" || true + sudo mysql -u $sqluser -p$sqlpass -e "source sql/framework.sql" || true + echo "Shinobi - Do you want to create a new user for viewing and managing cameras in Shinobi? You can do this later in the Superuser panel." + echo "(y)es or (N)o" + read mysqlDefaultData + if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then + escapeReplaceQuote='\\"' + groupKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1) + userID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userEmail=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)"@"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)".com" + userPasswordPlain=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userPasswordMD5=$(echo -n "$userPasswordPlain" | md5sum | awk '{print $1}') + userDetails='{"days":"10"}' + userDetails=$(echo "$userDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + echo $userDetailsNew + apiIP='0.0.0.0' + apiKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) + apiDetails='{"auth_socket":"1","get_monitors":"1","control_monitors":"1","get_logs":"1","watch_stream":"1","watch_snapshot":"1","watch_videos":"1","delete_videos":"1"}' + apiDetails=$(echo "$apiDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + rm sql/default_user.sql || true + echo "USE ccio;INSERT INTO Users (\`ke\`,\`uid\`,\`auth\`,\`mail\`,\`pass\`,\`details\`) VALUES (\"$groupKey\",\"$userID\",\"$apiKey\",\"$userEmail\",\"$userPasswordMD5\",\"$userDetails\");INSERT INTO API (\`code\`,\`ke\`,\`uid\`,\`ip\`,\`details\`) VALUES (\"$apiKey\",\"$groupKey\",\"$userID\",\"$apiIP\",\"$apiDetails\");" > "sql/default_user.sql" + sudo mysql -u $sqluser -p$sqlpass --database ccio -e "source sql/default_user.sql" > "INSTALL/log.txt" + echo "The following details will be shown again at the end of the installation." + echo "=====================================" + echo "======= Login Credentials =======" + echo "|| Username : $userEmail" + echo "|| Password : $userPasswordPlain" + echo "|| API Key : $apiKey" + echo "=====================================" + echo "=====================================" + echo "** To change these settings login to either to the Superuser panel or login to the dashboard as the user that was just created and open the Settings window. **" + fi + fi +fi +echo "=============" +echo "Shinobi - Install NPM Libraries" +sudo npm install +echo "=============" +echo "Shinobi - Install PM2" +sudo npm install pm2 -g +echo "Shinobi - Finished" +sudo chmod -R 755 . +touch INSTALL/installed.txt +if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then + echo "=====================================" > INSTALL/installed.txt + echo "======= Login Credentials =======" >> INSTALL/installed.txt + echo "|| Username : $userEmail" >> INSTALL/installed.txt + echo "|| Password : $userPasswordPlain" >> INSTALL/installed.txt + echo "|| API Key : $apiKey" >> INSTALL/installed.txt + echo "=====================================" >> INSTALL/installed.txt + echo "=====================================" >> INSTALL/installed.txt +fi +echo "Shinobi - Start Shinobi and set to start on boot?" +echo "(y)es or (N)o" +read startShinobi +if [ "$startShinobi" = "y" ] || [ "$startShinobi" = "Y" ]; then + sudo pm2 start camera.js + sudo pm2 start cron.js + sudo pm2 startup + sudo pm2 save + sudo pm2 list +fi +if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then + echo "details written to INSTALL/installed.txt" + echo "=====================================" + echo "======= Login Credentials =======" + echo "|| Username : $userEmail" + echo "|| Password : $userPasswordPlain" + echo "|| API Key : $apiKey" + echo "=====================================" + echo "=====================================" +fi +if [ ! "$sqliteormariadb" = "M" ] && [ ! "$sqliteormariadb" = "m" ]; then + echo "=====================================" + echo "||===== Install Completed =====||" + echo "=====================================" + echo "|| Login with the Superuser and create a new user!!" + echo "||===================================" + echo "|| Open http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080/super in your web browser." + echo "||===================================" + echo "|| Default Superuser : admin@shinobi.video" + echo "|| Default Password : admin" + echo "=====================================" + echo "=====================================" +else + echo "+=================================+" + echo "||===== Install Completed =====||" + echo "|| Access the main Shinobi panel at http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080 in your web browser." + echo "+=================================+" +fi \ No newline at end of file diff --git a/INSTALL/cuda4-part1.sh b/INSTALL/cuda4-part1.sh new file mode 100644 index 0000000..286f10b --- /dev/null +++ b/INSTALL/cuda4-part1.sh @@ -0,0 +1,15 @@ +#https://devtalk.nvidia.com/default/topic/1000340/cuda-setup-and-installation/-quot-nvidia-smi-has-failed-because-it-couldn-t-communicate-with-the-nvidia-driver-quot-ubuntu-16-04/4 +sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub +sudo echo "# NVIDIA Graphics Driver Repo (Added by Shinobi installer)" | sudo tee -a /etc/apt/sources.list +sudo echo "# Public Key : sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub" | sudo tee -a /etc/apt/sources.list +sudo echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 /" | sudo tee -a /etc/apt/sources.list +apt update +sudo apt -y install nvidia-340 nvidia-340-dev nvidia-modprobe libcuda1-340 libcuda1-340-updates nvidia-prime + +echo "After rebooting you need to run part 2. The file is named `cuda9-part2-after-reboot.sh`." +echo "Reboot is required. Do it now?" +echo "(y)es or (N)o" +read rebootTheMachineHomie +if [ "$rebootTheMachineHomie" = "y" ] || [ "$rebootTheMachineHomie" = "Y" ]; then + sudo reboot +fi \ No newline at end of file diff --git a/INSTALL/cuda9-part1.sh b/INSTALL/cuda9-part1.sh new file mode 100644 index 0000000..cc09bf7 --- /dev/null +++ b/INSTALL/cuda9-part1.sh @@ -0,0 +1,15 @@ +#https://devtalk.nvidia.com/default/topic/1000340/cuda-setup-and-installation/-quot-nvidia-smi-has-failed-because-it-couldn-t-communicate-with-the-nvidia-driver-quot-ubuntu-16-04/4 +sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub +sudo echo "# NVIDIA Graphics Driver Repo (Added by Shinobi installer)" | sudo tee -a /etc/apt/sources.list +sudo echo "# Public Key : sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub" | sudo tee -a /etc/apt/sources.list +sudo echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 /" | sudo tee -a /etc/apt/sources.list +apt update +sudo apt -y install cuda-drivers + +echo "After rebooting you need to run part 2. The file is named `cuda9-part2-after-reboot.sh`." +echo "Reboot is required. Do it now?" +echo "(y)es or (N)o" +read rebootTheMachineHomie +if [ "$rebootTheMachineHomie" = "y" ] || [ "$rebootTheMachineHomie" = "Y" ]; then + sudo reboot +fi \ No newline at end of file diff --git a/INSTALL/cuda9-part2-after-reboot.sh b/INSTALL/cuda9-part2-after-reboot.sh new file mode 100644 index 0000000..0335161 --- /dev/null +++ b/INSTALL/cuda9-part2-after-reboot.sh @@ -0,0 +1,2 @@ +sudo apt-get -y install cuda-toolkit-9-1 +nvidia-smi \ No newline at end of file diff --git a/INSTALL/ffmpeg.sh b/INSTALL/ffmpeg.sh new file mode 100644 index 0000000..31f8e18 --- /dev/null +++ b/INSTALL/ffmpeg.sh @@ -0,0 +1,22 @@ +#!/bin/bash +echo "=============" +echo "Install FFMPEG" +echo "What build of FFMPEG do you require?" +echo "If you don't know check your CPU specs for a hint." +echo "- 32bit" +echo "- 64bit" +echo "- armel-32bit" +echo "- armhf-32bit" +read ffmpegbuild +wget "https://s3.amazonaws.com/cloudcamio/ffmpeg-release-$ffmpegbuild-static.tar.xz" +tar xf "ffmpeg-release-$ffmpegbuild-static.tar.xz" +mv "ffmpeg-3.3-$ffmpegbuild-static/ffmpeg" "/usr/bin/ffmpeg" +mv "ffmpeg-3.3-$ffmpegbuild-static/ffmpeg-10bit" "/usr/bin/ffmpeg-10bit" +mv "ffmpeg-3.3-$ffmpegbuild-static/ffprobe" "/usr/bin/ffprobe" +mv "ffmpeg-3.3-$ffmpegbuild-static/ffserver" "/usr/bin/ffserver" +chmod +x /usr/bin/ffmpeg +chmod +x /usr/bin/ffmpeg-10bit +chmod +x /usr/bin/ffprobe +chmod +x /usr/bin/ffserver +rm -rf "ffmpeg-3.3-$ffmpegbuild-static" +rm -rf "ffmpeg-release-$ffmpegbuild-static.tar.xz" diff --git a/INSTALL/freebsd.sh b/INSTALL/freebsd.sh new file mode 100644 index 0000000..12da305 --- /dev/null +++ b/INSTALL/freebsd.sh @@ -0,0 +1,73 @@ +#!/bin/tcsh +echo "=========================================================" +echo "==== Shinobi : The Open Source CCTV and NVR Solution ====" +echo "=========================================================" +echo "This script should run as root inside your jail from the root" +echo "of the cloned git repository." +echo "To answer yes type the letter (y) in lowercase and press ENTER." +echo "Default is no (N). Skip any components you already have or don't need." +echo "=============" +echo "Shinobi - Do you want to Install Node.js?" +echo "(y)es or (N)o" +set nodejsinstall = $< +if ( $nodejsinstall == "y" ) then + pkg install -y node npm +endif +echo "=============" +echo "Shinobi - Do you want to Install FFMPEG?" +echo "(y)es or (N)o" +set ffmpeginstall = $< +if ( $ffmpeginstall == "y" ) then + pkg install -y ffmpeg libav x264 x265 +endif +echo "=============" +echo "Shinobi - Database Installation" +echo "WARNING - This requires an existing and running mariadb service." +echo "(y)es or (N)o" +set mysqlagreeData = $< +if ( $mysqlagreeData == "y" ) then + echo "What is your SQL Username?" + set sqluser = $< + echo "What is your SQL Password?" + set sqlpass = $< + echo "What is your SQL Host?" + set sqlhost = $< + echo "Installing mariadb client..." + pkg install -y mariadb102-client + echo "Installing database schema..." + mysql -h $sqlhost -u $sqluser -p$sqlpass -e "source sql/user.sql" || true + mysql -h $sqlhost -u $sqluser -p$sqlpass -e "source sql/framework.sql" || true + echo "Shinobi - Use the /super endpoint to create your super user." +endif +echo "=============" +echo "Shinobi - Install NPM Libraries" +npm install +echo "=============" +echo "Shinobi - Install PM2" +npm install pm2 -g +if (! -e "./conf.json" ) then + cp conf.sample.json conf.json +endif +if (! -e "./super.json" ) then + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + cp super.sample.json super.json +endif +echo "Shinobi - Start Shinobi?" +echo "(y)es or (N)o" +set startShinobi = $< +if ( $startShinobi == "y" ) then + set PM2BIN="$PWD/node_modules/pm2/bin" + $PM2BIN/pm2 start camera.js + $PM2BIN/pm2 start cron.js + $PM2BIN/pm2 save + $PM2BIN/pm2 list +endif +echo "Shinobi - Start on boot?" +echo "(y)es or (N)o" +set startupShinobi = $< +if ( $startupShinobi == "y" ) then + set PM2BIN="$PWD/node_modules/pm2/bin" + $PM2BIN/pm2 startup rcd +endif +echo "Shinobi - Finished" diff --git a/INSTALL/installDatabase.js b/INSTALL/installDatabase.js new file mode 100644 index 0000000..fc6e016 --- /dev/null +++ b/INSTALL/installDatabase.js @@ -0,0 +1,37 @@ +var knex = require('knex'); +if(config.databaseType===undefined){config.databaseType='mysql'} + +var databaseOptions = { + client: config.databaseType, + connection: config.db, +} +if(databaseOptions.client.indexOf('sqlite')>-1){ + databaseOptions.client = 'sqlite3'; + databaseOptions.useNullAsDefault = true; +} +if(databaseOptions.client === 'sqlite3' && databaseOptions.connection.filename === undefined){ + databaseOptions.connection.filename = __dirname+"/shinobi.sqlite" +} +s.databaseEngine = knex(databaseOptions) +s.sqlQuery = function(query,values,onMoveOn,hideLog){ + if(!values){values=[]} + if(typeof values === 'function'){ + var onMoveOn = values; + var values = []; + } + if(!onMoveOn){onMoveOn=function(){}} + return s.databaseEngine.raw(query,values) + .asCallback(function(err,r){ + if(err&&config.databaseLogs){ + s.systemLog('s.sqlQuery QUERY',query) + s.systemLog('s.sqlQuery ERROR',err) + } + if(onMoveOn) + if(typeof onMoveOn === 'function'){ + if(!r)r=[] + onMoveOn(err,r) + }else{ + console.log(onMoveOn) + } + }) +} \ No newline at end of file diff --git a/INSTALL/macos-part2.sh b/INSTALL/macos-part2.sh new file mode 100644 index 0000000..82d20fd --- /dev/null +++ b/INSTALL/macos-part2.sh @@ -0,0 +1,90 @@ + +#!/bin/bash +echo "=========================================================" +echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!==" +echo "=================== Mac OS Install Part 2 ===============" +echo "=========================================================" +echo "Shinobi - Database Installation" +echo "(y)es or (N)o" +read mysqlagreeData +if [ "$mysqlagreeData" = "y" ]; then + echo "Shinobi will now use root for database installation..." + echo "What is your SQL Username?" + read sqluser + echo "What is your SQL Password?" + read sqlpass + echo "You may now be asked for your Administator (root for Mac OS, not MySQL) password" + sudo mysql -u $sqluser -p$sqlpass -e "source sql/user.sql" || true + sudo mysql -u $sqluser -p$sqlpass -e "source sql/framework.sql" || true + echo "Shinobi - Do you want to create a new user for viewing and managing cameras in Shinobi? You can do this later in the Superuser panel." + echo "(y)es or (N)o" + read mysqlDefaultData + if [ "$mysqlDefaultData" = "y" ]; then + escapeReplaceQuote='\\"' + groupKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1) + userID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userEmail=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)"@"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)".com" + userPasswordPlain=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userPasswordMD5=$(echo -n "$userPasswordPlain" | md5sum | awk '{print $1}') + userDetails='{"days":"10"}' + userDetails=$(echo "$userDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + echo $userDetailsNew + apiIP='0.0.0.0' + apiKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) + apiDetails='{"auth_socket":"1","get_monitors":"1","control_monitors":"1","get_logs":"1","watch_stream":"1","watch_snapshot":"1","watch_videos":"1","delete_videos":"1"}' + apiDetails=$(echo "$apiDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + rm sql/default_user.sql || true + echo "USE ccio;INSERT INTO Users (\`ke\`,\`uid\`,\`auth\`,\`mail\`,\`pass\`,\`details\`) VALUES (\"$groupKey\",\"$userID\",\"$apiKey\",\"$userEmail\",\"$userPasswordMD5\",\"$userDetails\");INSERT INTO API (\`code\`,\`ke\`,\`uid\`,\`ip\`,\`details\`) VALUES (\"$apiKey\",\"$groupKey\",\"$userID\",\"$apiIP\",\"$apiDetails\");" > "sql/default_user.sql" + sudo mysql -u $sqluser -p$sqlpass --database ccio -e "source sql/default_user.sql" > "INSTALL/log.txt" + echo "The following details will be shown again at the end of the installation." + echo "=====================================" + echo "======= Login Credentials =======" + echo "|| Username : $userEmail" + echo "|| Password : $userPasswordPlain" + echo "|| API Key : $apiKey" + echo "=====================================" + echo "=====================================" + echo "** To change these settings login to either to the Superuser panel or login to the dashboard as the user that was just created and open the Settings window. **" + fi +fi +echo "=============" +echo "Shinobi - Install NPM Libraries" +sudo npm install +echo "=============" +echo "Shinobi - Install PM2" +sudo npm install pm2 -g +if [ ! -e "./conf.json" ]; then + sudo cp conf.sample.json conf.json +fi +if [ ! -e "./super.json" ]; then + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + sudo cp super.sample.json super.json +fi +echo "Shinobi - Finished" +touch INSTALL/installed.txt +sudo chmod -R 755 . +echo "=====================================" > INSTALL/installed.txt +echo "======= Login Credentials =======" >> INSTALL/installed.txt +echo "|| Username : $userEmail" >> INSTALL/installed.txt +echo "|| Password : $userPasswordPlain" >> INSTALL/installed.txt +echo "|| API Key : $apiKey" >> INSTALL/installed.txt +echo "=====================================" >> INSTALL/installed.txt +echo "=====================================" >> INSTALL/installed.txt +echo "Shinobi - Start Shinobi and set to start on boot?" +echo "(y)es or (N)o" +read startShinobi +if [ "$startShinobi" = "y" ]; then + sudo pm2 start camera.js + sudo pm2 startup + sudo pm2 save + sudo pm2 list +fi +echo "details written to INSTALL/installed.txt" +echo "=====================================" +echo "======= Login Credentials =======" +echo "|| Username : $userEmail" +echo "|| Password : $userPasswordPlain" +echo "|| API Key : $apiKey" +echo "=====================================" +echo "=====================================" diff --git a/INSTALL/macos.sh b/INSTALL/macos.sh new file mode 100644 index 0000000..0bf226e --- /dev/null +++ b/INSTALL/macos.sh @@ -0,0 +1,50 @@ +#!/bin/bash +echo "=========================================================" +echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!==" +echo "=================== Mac OS Install Part 1 ===============" +echo "=========================================================" +echo "To answer yes type the letter (y) in lowercase and press ENTER." +echo "Default is no (N). Skip any components you already have or don't need." +echo "=============" +echo "Shinobi - Do you want to Install Node.js?" +echo "(y)es or (N)o" +read nodejsinstall +if [ "$nodejsinstall" = "y" ]; then + curl -o node-v8.9.3.pkg https://nodejs.org/dist/v8.9.3/node-v8.9.3.pkg + sudo installer -pkg node-v8.9.3.pkg -target / + rm node-v8.9.3.pkg + sudo ln -s /usr/local/bin/node /usr/bin/nodejs +fi +echo "=============" +echo "Shinobi - Do you want to Install FFmpeg?" +echo "(y)es or (N)o" +read ffmpeginstall +if [ "$ffmpeginstall" = "y" ]; then + echo "Shinobi - Installing FFmpeg" + curl -o ffmpeg.zip https://cdn.shinobi.video/installers/ffmpeg-3.4.1-macos.zip + sudo unzip ffmpeg.zip + sudo rm ffmpeg.zip + sudo mv ffmpeg-3.4.1-macos/ffmpeg /usr/bin/ffmpeg + sudo mv ffmpeg-3.4.1-macos/ffplay /usr/bin/ffplay + sudo mv ffmpeg-3.4.1-macos/ffprobe /usr/bin/ffprobe + sudo mv ffmpeg-3.4.1-macos/ffserver /usr/bin/ffserver + sudo chmod +x /usr/local/bin/ffmpeg + sudo chmod +x /usr/local/bin/ffplay + sudo chmod +x /usr/local/bin/ffprobe + sudo chmod +x /usr/local/bin/ffserver +fi +echo "=============" +echo "Shinobi - Do you want to Install MySQL? Choose No if you have MySQL or MySQL already." +echo "(y)es or (N)o" +read mysqlagree +if [ "$mysqlagree" = "y" ]; then + echo "Shinobi - Installing MySQL" + bash <(curl -Ls http://git.io/eUx7rg) +fi +echo "=============" +echo "=============" +echo "You must now close this terminal window and reopen it." +echo "Reopen the Shinobi folder and run" +echo "sudo sh INSTALL/macos-part2.sh" +echo "=============" +echo "=============" \ No newline at end of file diff --git a/INSTALL/now.sh b/INSTALL/now.sh new file mode 100644 index 0000000..55ee23f --- /dev/null +++ b/INSTALL/now.sh @@ -0,0 +1,33 @@ +#!/bin/bash +echo "Shinobi Installer" +echo "========" +echo "Select your OS" +echo "If your OS is not on the list please refer to the docs." +echo "========" +echo "1. Ubuntu" +echo "2. CentOS" +echo "3. MacOS" +echo "4. FreeBSD" +echo "========" +read oschoicee +case $oschoicee in +"1") +chmod +x INSTALL/ubuntu.sh +sh INSTALL/ubuntu.sh + ;; +"2") +chmod +x INSTALL/centos.sh +INSTALL/centos.sh + ;; +"3") +chmod +x INSTALL/macos.sh +INSTALL/macos.sh + ;; +"4") +chmod +x INSTALL/freebsd.sh +INSTALL/freebsd.sh + ;; +*) + echo "Choice not found." + ;; +esac \ No newline at end of file diff --git a/INSTALL/openalpr-gpu-easy.sh b/INSTALL/openalpr-gpu-easy.sh new file mode 100644 index 0000000..0949629 --- /dev/null +++ b/INSTALL/openalpr-gpu-easy.sh @@ -0,0 +1,31 @@ +# Install prerequisites +# this includes all the ones missing from OpenALPR's guide. +sudo apt install libtesseract-dev git cmake build-essential libleptonica-dev -y +sudo apt install liblog4cplus-dev libcurl3-dev -y +sudo apt install libleptonica-dev -y +sudo apt install libcurl4-openssl-dev -y +sudo apt install liblog4cplus-dev -y +sudo apt install beanstalkd -y +sudo apt install openjdk-8-jdk -y + +# Clone the latest code from GitHub +git clone https://github.com/openalpr/openalpr.git + +# Setup the build directory +cd openalpr/src +mkdir build +cd build + +# setup the compile environment +cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_INSTALL_SYSCONFDIR:PATH=/etc –DCOMPILE_GPU=1 -D WITH_GPU_DETECTOR=ON .. + +# compile the library +make + +# Install the binaries/libraries to your local system (prefix is /usr) +sudo make install + +# Test the library +wget http://plates.openalpr.com/h786poj.jpg -O lp.jpg +alpr lp.jpg +rm lp.jpg \ No newline at end of file diff --git a/INSTALL/openalpr-opencl.sh b/INSTALL/openalpr-opencl.sh new file mode 100644 index 0000000..20ca09d --- /dev/null +++ b/INSTALL/openalpr-opencl.sh @@ -0,0 +1,3 @@ +sudo apt-get update && sudo apt install -y openalpr openalpr-daemon openalpr-utils libopenalpr-dev + +git clone https://github.com/openalpr/openalpr.git \ No newline at end of file diff --git a/INSTALL/opencv-cuda.sh b/INSTALL/opencv-cuda.sh new file mode 100644 index 0000000..c9f1045 --- /dev/null +++ b/INSTALL/opencv-cuda.sh @@ -0,0 +1,101 @@ +#!/bin/bash +#dlib +echo "=================" +echo "Installing OpenCV" +echo "=================" +if [ $(dpkg-query -W -f='${Status}' git 2>/dev/null | grep -c "ok installed") -eq 0 ]; then + echo "Installing Git..." + apt install git -y; +fi +sudo apt-get install libopenblas-dev -y +if [ ! -e "./opencv" ]; then + echo "Downloading OpenCV..." + git clone https://github.com/opencv/opencv.git + cd opencv + git checkout 3.4.0 + cd .. +fi +if [ ! -e "./opencv_contrib" ]; then + echo "Downloading OpenCV Modules..." + git clone https://github.com/opencv/opencv_contrib.git + cd opencv_contrib + git checkout 3.4.0 + cd .. +fi +echo "Opening OpenCV Directory..." +cd opencv +if [ ! -e "./build" ]; then + echo "Creating OpenCV Build Directory..." + mkdir build +fi +echo "Entering OpenCV Build Directory..." +cd build +echo "*****************" +if [ -f /etc/lsb-release ]; then + flavor=$(cat /var/log/installer/media-info) + echo "$flavor" + echo "*****************" + echo "Adding Additional Repository" + echo "http://security.ubuntu.com/ubuntu" + if [ "$flavor" = *"Artful"* ]; then + sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu artful-security main" + fi + if [ "$flavor" = *"Zesty"* ]; then + sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu zesty-security main" + fi + if [ "$flavor" = *"Xenial"* ]; then + sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main" + fi + if [ "$flavor" = *"Trusty"* ]; then + sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu trusty-security main" + fi + echo "Downloading Libraries" + sudo apt-get install libjpeg-dev libpango1.0-dev libgif-dev build-essential gcc-6 g++-6 -y; + sudo apt-get install libxvidcore-dev libx264-dev -y; + sudo apt-get install libatlas-base-dev gfortran -y; + + sudo apt install build-essential cmake pkg-config unzip ffmpeg qtbase5-dev python-dev python3-dev python-numpy python3-numpy libhdf5-dev libgtk-3-dev libdc1394-22 libdc1394-22-dev libjpeg-dev libtiff5-dev libtesseract-dev -y; + + sudo apt install libavcodec-dev libavformat-dev libswscale-dev libxine2-dev libgstreamer-plugins-base1.0-0 libgstreamer-plugins-base1.0-dev libpng16-16 libpng-dev libv4l-dev libtbb-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev v4l-utils libleptonica-dev -y + + echo "Setting CUDA Paths" + export LD_LIBRARY_PATH=/usr/local/cuda/lib + export PATH=$PATH:/usr/local/cuda/bin + echo "Configure OpenCV Build" + + cmake -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_NVCUVID=ON -D FORCE_VTK=ON -D WITH_XINE=ON -D WITH_CUDA=ON -D WITH_OPENGL=ON -D WITH_TBB=ON -D WITH_OPENCL=ON -D CMAKE_BUILD_TYPE=RELEASE -D CUDA_NVCC_FLAGS="-D_FORCE_INLINES --expt-relaxed-constexpr" -D WITH_GDAL=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules/ -D ENABLE_FAST_MATH=1 -D CUDA_FAST_MATH=1 -D WITH_CUBLAS=1 -D CXXFLAGS="-std=c++11" -DCMAKE_CXX_COMPILER=g++-6 -DCMAKE_C_COMPILER=gcc-6 .. + + echo "Start OpenCV Build" + make -j "$(nproc)" + echo "Install OpenCV Build" + sudo make install + sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf' + sudo ldconfig + sudo apt-get update +fi +if [ -f /etc/redhat-release ]; then + yum install -y \ + protobuf-devel \ + leveldb-devel \ + snappy-devel \ + opencv-devel \ + boost-devel \ + hdf5-devel \ + gflags-devel \ + glog-devel \ + lmdb-devel \ + cmake +fi +echo "Leaving OpenCV Directory" +cd ../.. + +echo "=============" +echo "Done installing OpenCV!" +echo "=============" +echo "Delete OpenCV source files? This will save a lot of space but it will be more tedious to uninstall OpenCV later." +echo "(y)es or (N)o" +read opencvuninstall +if [ "$opencvuninstall" = "y" ] || [ "$opencvuninstall" = "Y" ]; then + rm -rf opencv + rm -rf opencv_contrib +fi \ No newline at end of file diff --git a/INSTALL/shinobi b/INSTALL/shinobi new file mode 100644 index 0000000..3dd519b --- /dev/null +++ b/INSTALL/shinobi @@ -0,0 +1,10 @@ +#!/bin/bash +installationDirectory="/home/Shinobi" +if [ -e "$installationDirectory/INSTALL/installed.txt" ]; then + echo "Starting Shinobi" + pm2 start $installationDirectory/camera.js + pm2 start $installationDirectory/cron.js +fi +if [ ! -e "$installationDirectory/INSTALL/installed.txt" ]; then + chmod +x $installationDirectory/INSTALL/now.sh&&INSTALL/now.sh +fi \ No newline at end of file diff --git a/INSTALL/shinobi.service b/INSTALL/shinobi.service new file mode 100644 index 0000000..73138e2 --- /dev/null +++ b/INSTALL/shinobi.service @@ -0,0 +1,11 @@ +[Unit] +Description=ShinobiCCTV + +[Service] +WorkingDirectory=/home/Shinobi +Type=forking +ExecStart=/bin/bash INSTALL/start.sh +KillMode=process + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/INSTALL/start.sh b/INSTALL/start.sh new file mode 100644 index 0000000..a2439f7 --- /dev/null +++ b/INSTALL/start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +if [ -e "INSTALL/installed.txt" ]; then + echo "Starting Shinobi" + pm2 start camera.js + pm2 start cron.js +fi +if [ ! -e "INSTALL/installed.txt" ]; then + chmod +x INSTALL/now.sh&&INSTALL/now.sh +fi \ No newline at end of file diff --git a/INSTALL/ubuntu-easyinstall.sh b/INSTALL/ubuntu-easyinstall.sh new file mode 100644 index 0000000..075e2be --- /dev/null +++ b/INSTALL/ubuntu-easyinstall.sh @@ -0,0 +1,175 @@ +#!/bin/bash +echo "Shinobi - Do you want to Install Node.js?" +echo "(y)es or (N)o" +read nodejsinstall +if [ "$nodejsinstall" = "y" ]; then + wget https://deb.nodesource.com/setup_8.x + chmod +x setup_8.x + ./setup_8.x + sudo apt install nodejs -y + rm setup_8.x +fi + +#Detect Ubuntu Version +echo "=============" +echo " Detecting Ubuntu Version" +echo "=============" +declare -i getubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1) +echo "=============" +echo " Ubuntu Version: $getubuntuversion" +echo "=============" +if [[ "$getubuntuversion" == "16" || "$getubuntuversion" < "16" ]]; then + echo "=============" + echo "Shinobi - Get FFMPEG 3.x from ppa:jonathonf/ffmpeg-3" + sudo add-apt-repository ppa:jonathonf/ffmpeg-3 -y + sudo apt update -y && sudo apt install ffmpeg libav-tools x264 x265 -y + echo "=============" +else + echo "=============" + echo "Shinobi - Installing FFMPEG" + sudo apt install ffmpeg libav-tools x264 x265 -y + echo "=============" +fi + +# Install MariaDB +echo "Shinobi - Do you want to Install MariaDB? Choose No if you have MySQL." +echo "(y)es or (N)o" +read mysqlagree +if [ "$mysqlagree" = "y" ]; then + echo "Shinobi - Installing MariaDB" + echo "Password for root SQL user, If you are installing SQL now then you may put anything:" + read sqlpass + echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections + echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections + apt install mariadb-server -y + service mysql start +fi + +# Make sure files have correct perms +chmod -R 755 . + +# Database Installation +#Check If Mysql-Server is already installed + +echo "=============" +echo "Checking for mysql-server" +echo "=============" +dpkg -s mysql-server &> /dev/null +if [ $? -eq 0 ]; then + echo "+====================================+" + echo "| Warning MYSQL SERVER IS INSTALLED! |" + echo "+====================================+" + echo "| DO YOU WANT TO INSTALL MariaDB? |" + echo "| This will remove MYSQL-Server! |" + echo "+====================================+" + echo "Shinobi - Do you want to Install MariaDB?" + echo "(y)es or (N)o" + read installmariadb + if [ "$installmariadb" = "y" ]; then + echo "+=============================================+" + echo "| This will DESTORY ALL DATA ON MYSQL SERVER! |" + echo "+=============================================+" + echo "Please type the following to continue" + echo "DESTORY!" + read mysqlagree + if [ "$mysqlagree" = "DESTORY!" ]; then + echo "Shinobi - Installing MariaDB" + echo "Password for root SQL user, If you are installing SQL now then you may put anything:" + read sqlpass + echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections + echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections + #Create my.cnf file + echo "[client]" >> ~/.my.cnf + echo "user=root" >> ~/.my.cnf + echo "password=$sqlpass" >> ~/.my.cnf + chmod 755 ~/.my.cnf + apt install mariadb-server + service mysql start + fi + fi +else + echo "Shinobi - Do you want to Install MariaDB?" + echo "(y)es or (N)o" + read mysqlagree + if [ "$mysqlagree" = "y" ]; then + echo "Shinobi - Installing MariaDB" + echo "Password for root SQL user, If you are installing SQL now then you may put anything:" + read sqlpass + echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections + echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections + echo "[client]" >> ~/.my.cnf + echo "user=root" >> ~/.my.cnf + echo "password=$sqlpass" >> ~/.my.cnf + chmod 755 ~/.my.cnf + apt install mariadb-server -y + service mysql start + fi +fi + +chmod -R 755 . +echo "Shinobi - Database Installation" +echo "(y)es or (N)o" +read mysqlagreeData +if [ "$mysqlagreeData" = "y" ]; then + mysql -e "source sql/user.sql" || true + mysql -e "source sql/framework.sql" || true + echo "Shinobi - Do you want to Install Default Data (default_data.sql)?" + echo "(y)es or (N)o" + read mysqlDefaultData + if [ "$mysqlDefaultData" = "y" ]; then + escapeReplaceQuote='\\"' + groupKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1) + userID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userEmail=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)"@"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)".com" + userPasswordPlain=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userPasswordMD5=$(echo -n "$userPasswordPlain" | md5sum | awk '{print $1}') + userDetails='{"days":"10"}' + userDetails=$(echo "$userDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + echo $userDetailsNew + apiIP='0.0.0.0' + apiKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) + apiDetails='{"auth_socket":"1","get_monitors":"1","control_monitors":"1","get_logs":"1","watch_stream":"1","watch_snapshot":"1","watch_videos":"1","delete_videos":"1"}' + apiDetails=$(echo "$apiDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + rm sql/default_user.sql || true + echo "USE ccio;INSERT INTO Users (\`ke\`,\`uid\`,\`auth\`,\`mail\`,\`pass\`,\`details\`) VALUES (\"$groupKey\",\"$userID\",\"$apiKey\",\"$userEmail\",\"$userPasswordMD5\",\"$userDetails\");INSERT INTO API (\`code\`,\`ke\`,\`uid\`,\`ip\`,\`details\`) VALUES (\"$apiKey\",\"$groupKey\",\"$userID\",\"$apiIP\",\"$apiDetails\");" > "sql/default_user.sql" + mysql -u $sqluser -p$sqlpass --database ccio -e "source sql/default_user.sql" > "INSTALL/log.txt" + echo "=====================================" + echo "=======!! Login Credentials !!=======" + echo "|| Username : $userEmail" + echo "|| Password : $userPasswordPlain" + echo "|| API Key : $apiKey" + echo "=====================================" + echo "=====================================" + echo "** To change these settings login to either to the Superuser panel or login to the dashboard as the user that was just created and open the Settings window. **" + fi +fi + +# Install NPM Libraries +echo "=============" +echo "Shinobi - Install NPM Libraries" +npm install +echo "=============" + +#Install PM2 +echo "Shinobi - Install PM2" +sudo npm install pm2 -g +if [ ! -e "./conf.json" ]; then + cp conf.sample.json conf.json +fi +if [ ! -e "./super.json" ]; then + getip=$(ip route get 8.8.8.8 | awk '{print $NF; exit}') + echo "Admin panel default url: http://$getip:8080/super" + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + cp super.sample.json super.json +fi +echo "Shinobi - Finished" +touch INSTALL/installed.txt +echo "Shinobi - Start Shinobi?" +echo "(y)es or (N)o" +read startShinobi +if [ "$startShinobi" = "y" ]; then + pm2 start camera.js + pm2 start cron.js + pm2 list +fi \ No newline at end of file diff --git a/INSTALL/ubuntu.sh b/INSTALL/ubuntu.sh new file mode 100644 index 0000000..2e1ef46 --- /dev/null +++ b/INSTALL/ubuntu.sh @@ -0,0 +1,202 @@ +#!/bin/bash +echo "=========================================================" +echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!==" +echo "=========================================================" +echo "To answer yes type the letter (y) in lowercase and press ENTER." +echo "Default is no (N). Skip any components you already have or don't need." +echo "=============" +if [ ! -e "./conf.json" ]; then + sudo cp conf.sample.json conf.json +fi +if [ ! -e "./super.json" ]; then + echo "Shinobi - Do you want to enable superuser access?" + echo "This may be useful if passwords are forgotten or" + echo "if you would like to limit accessibility of an" + echo "account for business scenarios." + echo "(y)es or (N)o" + read createSuperJson + if [ "$createSuperJson" = "y" ] || [ "$createSuperJson" = "Y" ]; then + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + echo "* You can edit these settings in \"super.json\" located in the Shinobi directory." + sudo cp super.sample.json super.json + fi +fi +echo "Shinobi - Do you want to Install Node.js?" +echo "(y)es or (N)o" +read nodejsinstall +if [ "$nodejsinstall" = "y" ] || [ "$nodejsinstall" = "Y" ]; then + wget https://deb.nodesource.com/setup_8.x + chmod +x setup_8.x + ./setup_8.x + sudo apt install nodejs -y +fi +echo "=============" +echo "Shinobi - Do you want to Install FFMPEG?" +echo "(y)es or (N)o" +read ffmpeginstall +if [ "$ffmpeginstall" = "y" ] || [ "$ffmpeginstall" = "Y" ]; then + echo "Shinobi - Do you want to Install FFMPEG with `apt` or download a static version provided with `npm`?" + echo "(a)pt or (N)pm" + echo "Press [ENTER] for default (npm)" + read ffmpegstaticinstall + if [ "$ffmpegstaticinstall" = "a" ] || [ "$ffmpegstaticinstall" = "A" ]; then + #Detect Ubuntu Version + echo "=============" + echo " Detecting Ubuntu Version" + echo "=============" + declare -i getubuntuversion=$(lsb_release -r | awk '{print $2}' | cut -d . -f1) + echo "=============" + echo " Ubuntu Version: $getubuntuversion" + echo "=============" + if [[ "$getubuntuversion" == "16" || "$getubuntuversion" < "16" ]]; then + echo "=============" + echo "Shinobi - Get FFMPEG 3.x from ppa:jonathonf/ffmpeg-3" + sudo add-apt-repository ppa:jonathonf/ffmpeg-3 -y + sudo apt update -y && sudo apt install ffmpeg libav-tools x264 x265 -y + echo "=============" + else + echo "=============" + echo "Shinobi - Installing FFMPEG" + sudo apt install ffmpeg -y + echo "=============" + fi + else + sudo npm install ffmpeg-static + fi +fi +echo "=============" +echo "Shinobi - Do you want to use MariaDB or SQLite3?" +echo "SQLite3 is better for small installs" +echo "MariaDB (MySQL) is better for large installs" +echo "(S)QLite3 or (M)ariaDB?" +echo "Press [ENTER] for default (MariaDB)" +read sqliteormariadb +if [ "$sqliteormariadb" = "S" ] || [ "$sqliteormariadb" = "s" ]; then + sudo npm install jsonfile + sudo apt-get install sqlite3 libsqlite3-dev -y + sudo npm install sqlite3 + node ./tools/modifyConfiguration.js databaseType=sqlite3 + if [ ! -e "./shinobi.sqlite" ]; then + echo "Creating shinobi.sqlite for SQLite3..." + sudo cp sql/shinobi.sample.sqlite shinobi.sqlite + else + echo "shinobi.sqlite already exists. Continuing..." + fi +else + echo "Shinobi - Do you want to Install MariaDB? Choose No if you already have it." + echo "(y)es or (N)o" + read mysqlagree + if [ "$mysqlagree" = "y" ] || [ "$mysqlagree" = "Y" ]; then + echo "Shinobi - Installing MariaDB" + echo "Password for root SQL user, If you are installing SQL now then you may put anything:" + read sqlpass + echo "mariadb-server mariadb-server/root_password password $sqlpass" | debconf-set-selections + echo "mariadb-server mariadb-server/root_password_again password $sqlpass" | debconf-set-selections + sudo apt install mariadb-server -y + sudo service mysql start + fi + echo "=============" + echo "Shinobi - Database Installation" + echo "(y)es or (N)o" + read mysqlagreeData + if [ "$mysqlagreeData" = "y" ] || [ "$mysqlagreeData" = "Y" ]; then + if [ "$mysqlagree" = "y" ] || [ "$mysqlagree" = "Y" ]; then + sqluser="root" + fi + if [ ! "$mysqlagree" = "y" ]; then + echo "What is your SQL Username?" + read sqluser + echo "What is your SQL Password?" + read sqlpass + fi + sudo mysql -u $sqluser -p$sqlpass -e "source sql/user.sql" || true + sudo mysql -u $sqluser -p$sqlpass -e "source sql/framework.sql" || true + echo "Shinobi - Do you want to create a new user for viewing and managing cameras in Shinobi? You can do this later in the Superuser panel." + echo "(y)es or (N)o" + read mysqlDefaultData + if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then + escapeReplaceQuote='\\"' + groupKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1) + userID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userEmail=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)"@"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)".com" + userPasswordPlain=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1) + userPasswordMD5=$(echo -n "$userPasswordPlain" | md5sum | awk '{print $1}') + userDetails='{"days":"10"}' + userDetails=$(echo "$userDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + echo $userDetailsNew + apiIP='0.0.0.0' + apiKey=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) + apiDetails='{"auth_socket":"1","get_monitors":"1","control_monitors":"1","get_logs":"1","watch_stream":"1","watch_snapshot":"1","watch_videos":"1","delete_videos":"1"}' + apiDetails=$(echo "$apiDetails" | sed -e 's/"/'$escapeReplaceQuote'/g') + rm sql/default_user.sql || true + echo "USE ccio;INSERT INTO Users (\`ke\`,\`uid\`,\`auth\`,\`mail\`,\`pass\`,\`details\`) VALUES (\"$groupKey\",\"$userID\",\"$apiKey\",\"$userEmail\",\"$userPasswordMD5\",\"$userDetails\");INSERT INTO API (\`code\`,\`ke\`,\`uid\`,\`ip\`,\`details\`) VALUES (\"$apiKey\",\"$groupKey\",\"$userID\",\"$apiIP\",\"$apiDetails\");" > "sql/default_user.sql" + sudo mysql -u $sqluser -p$sqlpass --database ccio -e "source sql/default_user.sql" > "INSTALL/log.txt" + echo "The following details will be shown again at the end of the installation." + echo "=====================================" + echo "======= Login Credentials =======" + echo "|| Username : $userEmail" + echo "|| Password : $userPasswordPlain" + echo "|| API Key : $apiKey" + echo "=====================================" + echo "=====================================" + echo "** To change these settings login to either to the Superuser panel or login to the dashboard as the user that was just created and open the Settings window. **" + fi + fi +fi +echo "=============" +echo "Shinobi - Install NPM Libraries" +sudo npm install +echo "=============" +echo "Shinobi - Install PM2" +sudo npm install pm2 -g +echo "Shinobi - Finished" +sudo chmod -R 755 . +touch INSTALL/installed.txt +if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then + echo "=====================================" > INSTALL/installed.txt + echo "======= Login Credentials =======" >> INSTALL/installed.txt + echo "|| Username : $userEmail" >> INSTALL/installed.txt + echo "|| Password : $userPasswordPlain" >> INSTALL/installed.txt + echo "|| API Key : $apiKey" >> INSTALL/installed.txt + echo "=====================================" >> INSTALL/installed.txt + echo "=====================================" >> INSTALL/installed.txt +fi +echo "Shinobi - Start Shinobi and set to start on boot?" +echo "(y)es or (N)o" +read startShinobi +if [ "$startShinobi" = "y" ] || [ "$startShinobi" = "y" ]; then + sudo pm2 start camera.js + sudo pm2 start cron.js + sudo pm2 startup + sudo pm2 save + sudo pm2 list +fi +if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then + echo "details written to INSTALL/installed.txt" + echo "=====================================" + echo "======= Login Credentials =======" + echo "|| Username : $userEmail" + echo "|| Password : $userPasswordPlain" + echo "|| API Key : $apiKey" + echo "=====================================" + echo "=====================================" +fi +if [ ! "$sqliteormariadb" = "M" ] && [ ! "$sqliteormariadb" = "m" ]; then + echo "=====================================" + echo "||===== Install Completed =====||" + echo "=====================================" + echo "|| Login with the Superuser and create a new user!!" + echo "||===================================" + echo "|| Open http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080/super in your web browser." + echo "||===================================" + echo "|| Default Superuser : admin@shinobi.video" + echo "|| Default Password : admin" + echo "=====================================" + echo "=====================================" +else + echo "+=================================+" + echo "||===== Install Completed =====||" + echo "|| Access the main Shinobi panel at http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080 in your web browser." + echo "+=================================+" +fi \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..20d40b6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..03c1f9f --- /dev/null +++ b/README.md @@ -0,0 +1,146 @@ +# Shinobi Pro +### (Creative Commons v4.0) + +Shinobi is the Open Source CCTV Solution written in Node.JS. Designed with multiple account system, Streams by WebSocket, and Save to WebM. Shinobi can record IP Cameras and Local Cameras. + + + +# Key Aspects + +For an updated list of features visit the official website. http://shinobi.video/features + +- Time-lapse Viewer (Watch a hours worth of footage in a few minutes) +- 2-Factor Authentication +- Defeats stream limit imposed by browsers + - With Base64 (Stream Type) and JPEG Mode (Option) +- Records IP Cameras and Local Cameras +- Streams by WebSocket, HLS (includes audio), and MJPEG +- Save to WebM and MP4 + - Can save Audio +- Push Events - When a video is finished it will appear in the dashboard without a refresh +- Region Motion Detection (Similar to ZoneMinder Zone Detection) + - Represented by a Motion Guage on each monitor +- "No Motion" Notifications +- 1 Process for Each Camera to do both, Recording and Streaming +- Timeline for viewing Motion Events and Videos +- Sub-Accounts with permissions + - Monitor Viewing + - Monitor Editing + - Video Deleting + - Separate API keys for sub account +- Cron Filters can be set based on master account +- Stream Analyzer built-in (FFprobe GUI) +- Monitor Groups +- Can snapshot images from stream directly +- Lower Bandwith Mode (JPEG Mode) + - Snapshot (cgi-bin) must be enabled in Monitor Settings +- Control Cameras from Interface +- API + - Get videos + - Get monitors + - Change monitor modes : Disabled, Watch, Record + - Embedding streams +- Dashboard Framework made with Google Material Design Lite, jQuery, and Bootstrap + +## Asking for help + +Before asking questions it would nice if you read the docs :) http://shinobi.video + +After doing so please head on over to the Discord community chat for support. https://discordapp.com/invite/mdhmvuH + +The Issues section is only for bugs with the software. Comments and feature requests may be closed without comment. http://shinobi.video/docs/contribute + +Please be considerate of developer efforts. If you have simple questions, like "what does this button do?", please be sure to have read the docs entirely before asking. If you would like to skip reading the docs and ask away you can order a support package :) http://shinobi.video/support + +## Making Suggestions or Feature Requests + +You can post suggestions on the Forum in the Suggestions category. Please do not treat this channel like a "demands" window. Developer efforts are limited. Much more than many alternatives. + +when you have a suggestion please try and make the changes yourself then post a pull request to the `dev` branch. Then we can decide if it's a good change for Shinobi. If you don't know how to go about it and want to have me put it higher on my priority list you can order a support package :) Pretty Ferengi of me... but until we live in a world without money please support Shinobi :) Cheers! + +http://shinobi.video/support + +## Help make Shinobi the best Open Source CCTV Solution. +Donate - http://shinobi.video/docs/donate + +Ordering a License, Paid Support, or anything from here will allow a lot more time to be spent on Shinobi. + +Order Support - http://shinobi.video/support + +# Why make this? + +http://shinobi.video/why + +# What others say + +> "After trying zoneminder without success (heavy unstable and slow) I passed to Shinobi that despite being young spins a thousand times better (I have a setup with 16 cameras recording in FHD to ~ 10fps on a pentium of ~ 2009 and I turn with load below 1.5)." + +> *A Reddit user, /r/ItalyInformatica* + +  + +> "I would suggest Shinobi as a NVR. It's still in the early days but works a lot better than ZoneMinder for me. I'm able to record 16 cams at 1080p 15fps continously whith no load on server (Pentium E5500 3GB RAM) where zm crashed with 6 cams at 720p. Not to mention the better interface." + +> *A Reddit user, /r/HomeNetworking* + +# How to Install and Run + +> FOR DOCKER USERS : Docker is not officially supported and is not recommended. The kitematic method is provided for those who wish to quickly test Shinobi. The Docker files included in the master and dev branches are maintained by the community. If you would like support with Docker please find a community member who maintains the Docker files or please refer to Docker's forum. + +#### Fast Install (The Ninja Way) + +1. Become `root` to use the installer and run Shinobi. Use one of the following to do so. + + - Ubuntu 17.04, 17.10 + - `sudo su` + - CentOS 7 + - `su` + - MacOS 10.7(+) + - `su` +2. Download and run the installer. + +``` +bash <(curl -s https://raw.githubusercontent.com/ShinobiCCTV/Shinobi-Installer/master/shinobi-install.sh) +``` + +#### Elaborate Installs + +Installation Tutorials - http://shinobi.video/docs/start + +Troubleshooting Guide - http://shinobi.video/docs/start#trouble-section + +# Author + +Moe Alam + +Follow Shinobi on Twitter https://twitter.com/ShinobiCCTV + +Join the Community Chat + + + +# Support the Development + +Ordering a certificate or support package greatly boosts development. Please consider contributing :) + +http://shinobi.video/support + +# Links + +Documentation - http://shinobi.video/docs + +Donate - https://shinobi.video/docs/donate + +Tested Cameras and Systems - http://shinobi.video/docs/supported + +Features - http://shinobi.video/features + +Reddit (Forum) - https://www.reddit.com/r/ShinobiCCTV/ + +YouTube (Tutorials) - https://www.youtube.com/channel/UCbgbBLTK-koTyjOmOxA9msQ + +Discord (Community Chat) - https://discordapp.com/invite/mdhmvuH + +Twitter (News) - https://twitter.com/ShinobiCCTV + +Facebook (News) - https://www.facebook.com/Shinobi-1223193167773738/?ref=bookmarks \ No newline at end of file diff --git a/UPDATE.sh b/UPDATE.sh new file mode 100644 index 0000000..04b7a30 --- /dev/null +++ b/UPDATE.sh @@ -0,0 +1,24 @@ +#!/bin/bash +distro=$1 +repo=$2 +if [ -z "$distro" ]; then + distro='master' +fi +if [ -z "$repo" ]; then + repo='ShinobiCCTV' +fi +if [ "$repo" = "ShinobiCCTV" ]; then + productName="Shinobi Professional (Pro)" +else + productName="Shinobi Community Editon (CE)" +fi +git reset --hard +git pull +gitURL="https://github.com/$repo/Shinobi" +gitVersionNumber=$(git rev-parse HEAD) +theDateRightNow=$(date) +rm version.json +touch version.json +chmod 755 version.json +echo '{"Product" : "'"$productName"'" , "Branch" : "'"$distro"'" , "Version" : "'"$gitVersionNumber"'" , "Date" : "'"$theDateRightNow"'" , "Repository" : "'"$gitURL"'"}' > version.json +echo "Restart Shinobi for updates to take effect." \ No newline at end of file diff --git a/camera.js b/camera.js new file mode 100644 index 0000000..1e4e029 --- /dev/null +++ b/camera.js @@ -0,0 +1,6795 @@ +// +// Shinobi +// Copyright (C) 2016 Moe Alam, moeiscool +// +// +// # Donate +// +// If you like what I am doing here and want me to continue please consider donating :) +// PayPal : paypal@m03.ca +// +var fs = require('fs'); +process.on('uncaughtException', function (err) { + console.error('Uncaught Exception occured!'); + console.error(err.stack); +}); +var staticFFmpeg = false; +try{ + staticFFmpeg = require('ffmpeg-static').path; + if (!fs.existsSync(staticFFmpeg)) { + staticFFmpeg = false + console.log('"ffmpeg-static" from NPM has failed to provide a compatible library or has been corrupted.') + console.log('You may need to install FFmpeg manually or you can try running "npm uninstall ffmpeg-static && npm install ffmpeg-static".') + } +}catch(err){ + staticFFmpeg = false; + console.log('No Static FFmpeg. Continuing.') + //no static ffmpeg +} +var os = require('os'); +var URL = require('url'); +var path = require('path'); +var mysql = require('mysql'); +var moment = require('moment'); +var request = require("request"); +var express = require('express'); +var app = express(); +var http = require('http'); +var https = require('https'); +var server = http.createServer(app); +var bodyParser = require('body-parser'); +var CircularJSON = require('circular-json'); +var ejs = require('ejs'); +var io = new (require('socket.io'))(); +var execSync = require('child_process').execSync; +var exec = require('child_process').exec; +var spawn = require('child_process').spawn; +var socketIOclient = require('socket.io-client'); +var crypto = require('crypto'); +var webdav = require("webdav"); +var jsonfile = require("jsonfile"); +var connectionTester = require('connection-tester'); +var events = require('events'); +var onvif = require('node-onvif'); +var knex = require('knex'); +var Mp4Frag = require('mp4frag'); +var P2P = require('pipe2pam'); +var PamDiff = require('pam-diff'); +var httpProxy = require('http-proxy'); +var proxy = httpProxy.createProxyServer({}) +var location = {} +location.super = __dirname+'/super.json' +location.config = __dirname+'/conf.json' +location.languages = __dirname+'/languages' +location.definitions = __dirname+'/definitions' +var config = require(location.config); +if(!config.productType){ + config.productType='CE' +} +if(config.productType==='Pro'){ + var LdapAuth = require('ldapauth-fork'); +} +if(!config.language){ + config.language='en_CA' +} +try{ + var lang = require(location.languages+'/'+config.language+'.json'); +}catch(er){ + console.error(er) + console.log('There was an error loading your language file.') + var lang = require(location.languages+'/en_CA.json'); +} +try{ + var definitions = require(location.definitions+'/'+config.language+'.json'); +}catch(er){ + console.error(er) + console.log('There was an error loading your language file.') + var definitions = require(location.definitions+'/en_CA.json'); +} +process.send = process.send || function () {}; +if(config.mail){ + var nodemailer = require('nodemailer').createTransport(config.mail); +} +//config defaults +if(config.cpuUsageMarker===undefined){config.cpuUsageMarker='%Cpu'} +if(config.customCpuCommand===undefined){config.customCpuCommand=null} +if(config.autoDropCache===undefined){config.autoDropCache=true} +if(config.doSnapshot===undefined){config.doSnapshot=true} +if(config.restart===undefined){config.restart={}} +if(config.systemLog===undefined){config.systemLog=true} +if(config.deleteCorruptFiles===undefined){config.deleteCorruptFiles=true} +if(config.restart.onVideoNotExist===undefined){config.restart.onVideoNotExist=true} +if(config.ip===undefined||config.ip===''||config.ip.indexOf('0.0.0.0')>-1){config.ip='localhost'}else{config.bindip=config.ip}; +if(config.cron===undefined)config.cron={}; +if(config.cron.enabled===undefined)config.cron.enabled=true; +if(config.cron.deleteOld===undefined)config.cron.deleteOld=true; +if(config.cron.deleteOrphans===undefined)config.cron.deleteOrphans=false; +if(config.cron.deleteNoVideo===undefined)config.cron.deleteNoVideo=true; +if(config.cron.deleteNoVideoRecursion===undefined)config.cron.deleteNoVideoRecursion=false; +if(config.cron.deleteOverMax===undefined)config.cron.deleteOverMax=true; +if(config.cron.deleteOverMaxOffset===undefined)config.cron.deleteOverMaxOffset=0.9; +if(config.cron.deleteLogs===undefined)config.cron.deleteLogs=true; +if(config.cron.deleteEvents===undefined)config.cron.deleteEvents=true; +if(config.cron.deleteFileBins===undefined)config.cron.deleteFileBins=true; +if(config.cron.interval===undefined)config.cron.interval=1; +if(config.databaseType===undefined){config.databaseType='mysql'} +if(config.pluginKeys===undefined)config.pluginKeys={}; +if(config.databaseLogs===undefined){config.databaseLogs=false} +if(config.useUTC===undefined){config.useUTC=false} +if(config.pipeAddition===undefined){config.pipeAddition=7}else{config.pipeAddition=parseInt(config.pipeAddition)} +//Web Paths +if(config.webPaths===undefined){config.webPaths={}} + //main access URI + if(config.webPaths.home===undefined){config.webPaths.index='/'} + //Super User URI + if(config.webPaths.super===undefined){config.webPaths.super='/super'} + //Admin URI + if(config.webPaths.admin===undefined){config.webPaths.admin='/admin'} +//Page Rander Paths +if(config.renderPaths===undefined){config.renderPaths={}} + //login page + if(config.renderPaths.index===undefined){config.renderPaths.index='pages/index'} + //dashboard page + if(config.renderPaths.home===undefined){config.renderPaths.home='pages/home'} + //sub-account administration page + if(config.renderPaths.admin===undefined){config.renderPaths.admin='pages/admin'} + //superuser page + if(config.renderPaths.super===undefined){config.renderPaths.super='pages/super'} + //2-Factor Auth page + if(config.renderPaths.factorAuth===undefined){config.renderPaths.factorAuth='pages/factor'} + //Streamer (Dashbcam Prototype) page + if(config.renderPaths.streamer===undefined){config.renderPaths.streamer='pages/streamer'} + //Streamer v2 (Dashbcam) page + if(config.renderPaths.dashcam===undefined){config.renderPaths.dashcam='pages/dashcam'} + //embeddable widget page + if(config.renderPaths.embed===undefined){config.renderPaths.embed='pages/embed'} + //mjpeg full screen page + if(config.renderPaths.mjpeg===undefined){config.renderPaths.mjpeg='pages/mjpeg'} + //gridstack only page + if(config.renderPaths.grid===undefined){config.renderPaths.grid='pages/grid'} +//Child Nodes +if(config.childNodes===undefined)config.childNodes = {}; + //enabled + if(config.childNodes.enabled===undefined)config.childNodes.enabled = false; + //mode, set value as `child` for all other machines in the cluster + if(config.childNodes.mode===undefined)config.childNodes.mode = 'master'; + //child node connection port + if(config.childNodes.port===undefined)config.childNodes.port = 8288; + //child node connection key + if(config.childNodes.key===undefined)config.childNodes.key = [ + '3123asdasdf1dtj1hjk23sdfaasd12asdasddfdbtnkkfgvesra3asdsd3123afdsfqw345' + ]; + + +s={ + factorAuth : {}, + totalmem : os.totalmem(), + platform : os.platform(), + s : JSON.stringify, + isWin : (process.platform==='win32'), + utcOffset : moment().utcOffset() +}; +//load languages dynamically +s.loadedLanguages={} +s.loadedLanguages[config.language]=lang; +s.getLanguageFile=function(rule){ + if(rule&&rule!==''){ + var file=s.loadedLanguages[file] + if(!file){ + try{ + s.loadedLanguages[rule]=require(location.languages+'/'+rule+'.json') + file=s.loadedLanguages[rule] + }catch(err){ + file=lang + } + } + }else{ + file=lang + } + return file +} +//load defintions dynamically +s.loadedDefinitons={} +s.loadedDefinitons[config.language]=definitions; +s.getDefinitonFile=function(rule){ + if(rule&&rule!==''){ + var file=s.loadedDefinitons[file] + if(!file){ + try{ + s.loadedDefinitons[rule]=require(location.definitions+'/'+rule+'.json') + file=s.loadedDefinitons[rule] + }catch(err){ + file=definitions + } + } + }else{ + file=definitions + } + return file +} +var databaseOptions = { + client: config.databaseType, + connection: config.db, +} +if(databaseOptions.client.indexOf('sqlite')>-1){ + databaseOptions.client = 'sqlite3'; + databaseOptions.useNullAsDefault = true; +} +if(databaseOptions.client === 'sqlite3' && databaseOptions.connection.filename === undefined){ + databaseOptions.connection.filename = __dirname+"/shinobi.sqlite" +} +s.databaseEngine = knex(databaseOptions) +s.sqlDate = function(value){ + var dateQueryFunction = '' + if(databaseOptions.client === 'sqlite3'){ + value = value.toLowerCase() + if (value.slice(-1) !== 's') { + value = value+'s' + } + dateQueryFunction = "datetime('now', '-"+value+"')" + }else{ + value = value.toUpperCase() + if (value.slice(-1) === 'S') { + value = value.slice(0, -1); + } + dateQueryFunction = "DATE_SUB(NOW(), INTERVAL "+value+")" + } + return dateQueryFunction +} +s.mergeQueryValues = function(query,values){ + if(!values){values=[]} + var valuesNotFunction = true; + if(typeof values === 'function'){ + var onMoveOn = values; + var values = []; + valuesNotFunction = false; + } + if(!onMoveOn){onMoveOn=function(){}} + if(values&&valuesNotFunction){ + var splitQuery = query.split('?') + var newQuery = '' + splitQuery.forEach(function(v,n){ + newQuery += v + if(values[n]){ + if(isNaN(values[n])){ + newQuery += "'"+values[n]+"'" + }else{ + newQuery += values[n] + } + } + }) + }else{ + newQuery = query + } + return newQuery +} +s.sqlQuery = function(query,values,onMoveOn,hideLog){ + if(!values){values=[]} + if(typeof values === 'function'){ + var onMoveOn = values; + var values = []; + } + if(!onMoveOn){onMoveOn=function(){}} + var mergedQuery = s.mergeQueryValues(query,values) + return s.databaseEngine.raw(query,values) + .asCallback(function(err,r){ + if(err&&config.databaseLogs){ + s.systemLog('s.sqlQuery QUERY',query) + s.systemLog('s.sqlQuery ERROR',err) + } + if(onMoveOn && typeof onMoveOn === 'function'){ + switch(databaseOptions.client){ + case'sqlite3': + if(!r)r=[] + break; + default: + if(r)r=r[0] + break; + } + onMoveOn(err,r) + } + }) +} +//kill any ffmpeg running +s.ffmpegKill=function(){ + var cmd='' + if(s.isWin===true){ + cmd="Taskkill /IM ffmpeg.exe /F" + }else{ + cmd="ps aux | grep -ie ffmpeg | awk '{print $2}' | xargs kill -9" + } + exec(cmd,{detached: true}) +}; +process.on('exit',s.ffmpegKill.bind(null,{cleanup:true})); +process.on('SIGINT',s.ffmpegKill.bind(null, {exit:true})); +s.checkRelativePath=function(x){ + if(x.charAt(0)!=='/'){ + x=__dirname+'/'+x + } + return x +} +s.checkCorrectPathEnding=function(x){ + var length=x.length + if(x.charAt(length-1)!=='/'){ + x=x+'/' + } + return x.replace('__DIR__',__dirname) +} +s.md5=function(x){return crypto.createHash('md5').update(x).digest("hex");} +//send data to detector plugin +s.ocvTx=function(data){ + if(!s.ocv){return} + if(s.ocv.isClientPlugin===true){ + s.tx(data,s.ocv.id) + }else{ + s.connectedPlugins[s.ocv.plug].tx(data) + } +} +//send data to socket client function +s.tx=function(z,y,x){if(x){return x.broadcast.to(y).emit('f',z)};io.to(y).emit('f',z);} +s.txWithSubPermissions=function(z,y,permissionChoices){ + if(typeof permissionChoices==='string'){ + permissionChoices=[permissionChoices] + } + if(s.group[z.ke]){ + Object.keys(s.group[z.ke].users).forEach(function(v){ + var user = s.group[z.ke].users[v] + if(user.details.sub){ + if(user.details.allmonitors!=='1'){ + var valid=0 + var checked=permissionChoices.length + permissionChoices.forEach(function(b){ + if(user.details[b].indexOf(z.mid)!==-1){ + ++valid + } + }) + if(valid===checked){ + s.tx(z,user.cnid) + } + }else{ + s.tx(z,user.cnid) + } + }else{ + s.tx(z,user.cnid) + } + }) + } +} +//load camera controller vars +s.nameToTime=function(x){x=x.split('.')[0].split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;} +s.ratio=function(width,height,ratio){ratio = width / height;return ( Math.abs( ratio - 4 / 3 ) < Math.abs( ratio - 16 / 9 ) ) ? '4:3' : '16:9';} +s.randomNumber=function(x){ + if(!x){x=10}; + return Math.floor((Math.random() * x) + 1); +}; +s.gid=function(x){ + if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.nid=function(x){ + if(!x){x=6};var t = "";var p = "0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.formattedTime_withOffset=function(e,x){ + if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'}; + e=s.timeObject(e);if(config.utcOffset){e=e.utcOffset(config.utcOffset)} + return e.format(x); +} +s.formattedTime=function(e,x){ + if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'}; + return s.timeObject(e).format(x); +} +s.utcToLocal = function(time){ + return moment.utc(time).utcOffset(s.utcOffset).format() +} +s.localTimeObject = function(e,x){ + return moment(e) +} +if(config.useUTC === true){ + s.timeObject = function(time){ + return moment(time).utc() + } +}else{ + s.timeObject = moment +} +console.log('config.useUTC',config.useUTC) +s.ipRange=function(start_ip, end_ip) { + var start_long = s.toLong(start_ip); + var end_long = s.toLong(end_ip); + if (start_long > end_long) { + var tmp=start_long; + start_long=end_long + end_long=tmp; + } + var range_array = []; + var i; + for (i=start_long; i<=end_long;i++) { + range_array.push(s.fromLong(i)); + } + return range_array; +} +s.portRange=function(lowEnd,highEnd){ + var list = []; + for (var i = lowEnd; i <= highEnd; i++) { + list.push(i); + } + return list; +} +//toLong taken from NPM package 'ip' +s.toLong=function(ip) { + var ipl = 0; + ip.split('.').forEach(function(octet) { + ipl <<= 8; + ipl += parseInt(octet); + }); + return(ipl >>> 0); +}; + +//fromLong taken from NPM package 'ip' +s.fromLong=function(ipl) { + return ((ipl >>> 24) + '.' + + (ipl >> 16 & 255) + '.' + + (ipl >> 8 & 255) + '.' + + (ipl & 255) ); +}; +s.getFunctionParamNames = function(func) { + var fnStr = func.toString().replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, ''); + var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(/([^\s,]+)/g); + if(result === null) + result = []; + return result; +} +s.createPamDiffRegionArray = function(regions,globalSensitivity,fullFrame){ + var pamDiffCompliantArray = [], + arrayForOtherStuff = [], + json + try{ + json = JSON.parse(regions) + }catch(err){ + json = regions + } + if(fullFrame){ + json[fullFrame.name]=fullFrame; + } + Object.values(json).forEach(function(region){ + region.polygon = []; + region.points.forEach(function(points){ + region.polygon.push({x:parseFloat(points[0]),y:parseFloat(points[1])}) + }) + if(region.sensitivity===''){ + region.sensitivity = globalSensitivity + }else{ + region.sensitivity = parseInt(region.sensitivity) + } + pamDiffCompliantArray.push({name: region.name, difference: 9, percent: region.sensitivity, polygon:region.polygon}) + arrayForOtherStuff[region.name] = region; + }) + if(pamDiffCompliantArray.length===0){pamDiffCompliantArray = null} + return {forPam:pamDiffCompliantArray,notForPam:arrayForOtherStuff}; +} +s.getRequest = function(url,callback){ + return http.get(url, function(res){ + var body = ''; + res.on('data', function(chunk){ + body += chunk; + }); + res.on('end',function(){ + try{body = JSON.parse(body)}catch(err){} + callback(body) + }); + }).on('error', function(e){ +// s.systemLog("Get Snapshot Error", e); + }); +} +s.kill=function(x,e,p){ + if(s.group[e.ke]&&s.group[e.ke].mon[e.id]&&s.group[e.ke].mon[e.id].spawn !== undefined){ + if(s.group[e.ke].mon[e.id].spawn){ + s.group[e.ke].mon[e.id].spawn.stdio[3].unpipe(); +// if(s.group[e.ke].mon[e.id].p2pStream){s.group[e.ke].mon[e.id].p2pStream.unpipe();} + if(s.group[e.ke].mon[e.id].p2p){s.group[e.ke].mon[e.id].p2p.unpipe();} + delete(s.group[e.ke].mon[e.id].p2pStream) + delete(s.group[e.ke].mon[e.id].p2p) + delete(s.group[e.ke].mon[e.id].pamDiff) + try{ + s.group[e.ke].mon[e.id].spawn.removeListener('end',s.group[e.ke].mon[e.id].spawn_exit); + s.group[e.ke].mon[e.id].spawn.removeListener('exit',s.group[e.ke].mon[e.id].spawn_exit); + delete(s.group[e.ke].mon[e.id].spawn_exit); + }catch(er){} + } + clearTimeout(s.group[e.ke].mon[e.id].checker); + delete(s.group[e.ke].mon[e.id].checker); + clearTimeout(s.group[e.ke].mon[e.id].checkStream); + delete(s.group[e.ke].mon[e.id].checkStream); + clearTimeout(s.group[e.ke].mon[e.id].watchdog_stop); + delete(s.group[e.ke].mon[e.id].watchdog_stop); + delete(s.group[e.ke].mon[e.id].lastJpegDetectorFrame); + if(e&&s.group[e.ke].mon[e.id].record){ + clearTimeout(s.group[e.ke].mon[e.id].record.capturing); +// if(s.group[e.ke].mon[e.id].record.request){s.group[e.ke].mon[e.id].record.request.abort();delete(s.group[e.ke].mon[e.id].record.request);} + }; + if(s.group[e.ke].mon[e.id].childNode){ + s.cx({f:'kill',d:s.init('noReference',e)},s.group[e.ke].mon[e.id].childNodeId) + }else{ + if(!x||x===1){return}; + p=x.pid; + if(s.group[e.ke].mon_conf[e.id].type===('dashcam'||'socket'||'jpeg'||'pipe')){ + x.stdin.pause();setTimeout(function(){x.kill('SIGTERM');delete(x);},500) + }else{ + try{ + x.stdin.setEncoding('utf8');x.stdin.write('q'); + }catch(er){} + } + setTimeout(function(){exec('kill -9 '+p,{detached: true})},1000) + } + } +} +//user log +s.log=function(e,x){ + if(!x||!e.mid){return} + if((e.details&&e.details.sqllog==='1')||e.mid.indexOf('$')>-1){ + s.sqlQuery('INSERT INTO Logs (ke,mid,info) VALUES (?,?,?)',[e.ke,e.mid,s.s(x)]); + } + s.tx({f:'log',ke:e.ke,mid:e.mid,log:x,time:s.timeObject()},'GRPLOG_'+e.ke); +// s.systemLog('s.log : ',{f:'log',ke:e.ke,mid:e.mid,log:x,time:s.timeObject()},'GRP_'+e.ke) +} +//system log +s.systemLog=function(q,w,e){ + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + if(typeof q==='string'&&s.databaseEngine){ + s.sqlQuery('INSERT INTO Logs (ke,mid,info) VALUES (?,?,?)',['$','$SYSTEM',s.s({type:q,msg:w})]); + s.tx({f:'log',log:{time:s.timeObject(),ke:'$',mid:'$SYSTEM',time:s.timeObject(),info:s.s({type:q,msg:w})}},'$'); + } + return console.log(s.timeObject().format(),q,w,e) + } +} +//SSL options +if(config.ssl&&config.ssl.key&&config.ssl.cert){ + config.ssl.key=fs.readFileSync(s.checkRelativePath(config.ssl.key),'utf8') + config.ssl.cert=fs.readFileSync(s.checkRelativePath(config.ssl.cert),'utf8') + if(config.ssl.port===undefined){ + config.ssl.port=443 + } + if(config.ssl.bindip===undefined){ + config.ssl.bindip=config.bindip + } + if(config.ssl.ca&&config.ssl.ca instanceof Array){ + config.ssl.ca.forEach(function(v,n){ + config.ssl.ca[n]=fs.readFileSync(s.checkRelativePath(v),'utf8') + }) + } + var serverHTTPS = https.createServer(config.ssl,app); + serverHTTPS.listen(config.ssl.port,config.bindip,function(){ + console.log('SSL '+lang.Shinobi+' - SSL PORT : '+config.ssl.port); + }); + io.attach(serverHTTPS); +} +//start HTTP +server.listen(config.port,config.bindip,function(){ + console.log(lang.Shinobi+' - PORT : '+config.port); +}); +io.attach(server); +console.log('NODE.JS version : '+execSync("node -v")) +//ffmpeg location +if(!config.ffmpegDir){ + if(staticFFmpeg !== false){ + config.ffmpegDir = staticFFmpeg + }else{ + if(s.isWin===true){ + config.ffmpegDir = __dirname+'/ffmpeg/ffmpeg.exe' + }else{ + config.ffmpegDir = 'ffmpeg' + } + } +} +//ffmpeg version +s.ffmpegVersion=execSync(config.ffmpegDir+" -version").toString().split('Copyright')[0].replace('ffmpeg version','').trim() +console.log('FFMPEG version : '+s.ffmpegVersion) +if(s.ffmpegVersion.indexOf(': 2.')>-1){ + s.systemLog('FFMPEG is too old : '+s.ffmpegVersion+', Needed : 3.2+',err) + return +} +//directories +s.group={}; +if(!config.windowsTempDir&&s.isWin===true){config.windowsTempDir='C:/Windows/Temp'} +if(!config.defaultMjpeg){config.defaultMjpeg=__dirname+'/web/libs/img/bg.jpg'} +//default stream folder check +if(!config.streamDir){ + if(s.isWin===false){ + config.streamDir='/dev/shm' + }else{ + config.streamDir=config.windowsTempDir + } + if(!fs.existsSync(config.streamDir)){ + config.streamDir=__dirname+'/streams/' + }else{ + config.streamDir+='/streams/' + } +} +if(!config.videosDir){config.videosDir=__dirname+'/videos/'} +if(!config.binDir){config.binDir=__dirname+'/fileBin/'} +if(!config.addStorage){config.addStorage=[]} +s.dir={ + videos:s.checkCorrectPathEnding(config.videosDir), + streams:s.checkCorrectPathEnding(config.streamDir), + fileBin:s.checkCorrectPathEnding(config.binDir), + addStorage:config.addStorage, + languages:location.languages+'/' +}; +//streams dir +if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); +} +//videos dir +if(!fs.existsSync(s.dir.videos)){ + fs.mkdirSync(s.dir.videos); +} +//fileBin dir +if(!fs.existsSync(s.dir.fileBin)){ + fs.mkdirSync(s.dir.fileBin); +} +//additional storage areas +s.dir.addStorage.forEach(function(v,n){ + v.path=s.checkCorrectPathEnding(v.path) + if(!fs.existsSync(v.path)){ + fs.mkdirSync(v.path); + } +}) +////Camera Controller +s.init=function(x,e,k,fn){ + if(!e){e={}} + if(!k){k={}} + switch(x){ + case 0://init camera + if(!s.group[e.ke]){s.group[e.ke]={}}; + if(!s.group[e.ke].fileBin){s.group[e.ke].fileBin={}}; + if(!s.group[e.ke].mon){s.group[e.ke].mon={}} + if(!s.group[e.ke].sizeChangeQueue){s.group[e.ke].sizeChangeQueue=[]} + if(!s.group[e.ke].sizePurgeQueue){s.group[e.ke].sizePurgeQueue=[]} + if(!s.group[e.ke].users){s.group[e.ke].users={}} + if(!s.group[e.ke].mon[e.mid]){s.group[e.ke].mon[e.mid]={}} + if(!s.group[e.ke].mon[e.mid].streamIn){s.group[e.ke].mon[e.mid].streamIn={}}; + if(!s.group[e.ke].mon[e.mid].emitterChannel){s.group[e.ke].mon[e.mid].emitterChannel={}}; + if(!s.group[e.ke].mon[e.mid].mp4frag){s.group[e.ke].mon[e.mid].mp4frag={}}; + if(!s.group[e.ke].mon[e.mid].firstStreamChunk){s.group[e.ke].mon[e.mid].firstStreamChunk={}}; + if(!s.group[e.ke].mon[e.mid].contentWriter){s.group[e.ke].mon[e.mid].contentWriter={}}; + if(!s.group[e.ke].mon[e.mid].childNodeStreamWriters){s.group[e.ke].mon[e.mid].childNodeStreamWriters={}}; + if(!s.group[e.ke].mon[e.mid].eventBasedRecording){s.group[e.ke].mon[e.mid].eventBasedRecording={}}; + if(!s.group[e.ke].mon[e.mid].watch){s.group[e.ke].mon[e.mid].watch={}}; + if(!s.group[e.ke].mon[e.mid].fixingVideos){s.group[e.ke].mon[e.mid].fixingVideos={}}; + if(!s.group[e.ke].mon[e.mid].record){s.group[e.ke].mon[e.mid].record={yes:e.record}}; + if(!s.group[e.ke].mon[e.mid].started){s.group[e.ke].mon[e.mid].started=0}; + if(s.group[e.ke].mon[e.mid].delete){clearTimeout(s.group[e.ke].mon[e.mid].delete)} + if(!s.group[e.ke].mon_conf){s.group[e.ke].mon_conf={}} + s.init('apps',e) + break; + case'group': + if(!s.group[e.ke]){ + s.group[e.ke]={} + } + if(!s.group[e.ke].init){ + s.group[e.ke].init={} + } + if(!e.limit||e.limit===''){e.limit=10000}else{e.limit=parseFloat(e.limit)} + //save global space limit for group key (mb) + s.group[e.ke].sizeLimit=e.limit; + //save global used space as megabyte value + s.group[e.ke].usedSpace=e.size/1000000; + //emit the changes to connected users + s.init('diskUsedEmit',e) + break; + case'apps': + if(!s.group[e.ke].init){ + s.group[e.ke].init={}; + } + if(!s.group[e.ke].webdav||!s.group[e.ke].sizeLimit){ + s.sqlQuery('SELECT * FROM Users WHERE ke=? AND details NOT LIKE ?',[e.ke,'%"sub"%'],function(ar,r){ + if(r&&r[0]){ + r=r[0]; + ar=JSON.parse(r.details); + //owncloud/webdav + if(ar.webdav_user&& + ar.webdav_user!==''&& + ar.webdav_pass&& + ar.webdav_pass!==''&& + ar.webdav_url&& + ar.webdav_url!=='' + ){ + if(!ar.webdav_dir||ar.webdav_dir===''){ + ar.webdav_dir='/'; + if(ar.webdav_dir.slice(-1)!=='/'){ar.webdav_dir+='/';} + } + s.group[e.ke].webdav = webdav( + ar.webdav_url, + ar.webdav_user, + ar.webdav_pass + ); + } + Object.keys(ar).forEach(function(v){ + s.group[e.ke].init[v]=ar[v] + }) + } + }); + } + break; + case'sync': + e.cn=Object.keys(s.childNodes); + e.cn.forEach(function(v){ + if(s.group[e.ke]){ + s.cx({f:'sync',sync:s.init('noReference',s.group[e.ke].mon_conf[e.mid]),ke:e.ke,mid:e.mid},s.childNodes[v].cnid); + } + }); + break; + case'noReference': + x={keys:Object.keys(e),ar:{}}; + x.keys.forEach(function(v){ + if(v!=='last_frame'&&v!=='record'&&v!=='spawn'&&v!=='running'&&(v!=='time'&&typeof e[v]!=='function')){x.ar[v]=e[v];} + }); + return x.ar; + break; + case'url': + //build a complete url from pieces + e.authd=''; + if(e.details.muser&&e.details.muser!==''&&e.host.indexOf('@')===-1) { + e.authd=e.details.muser+':'+e.details.mpass+'@'; + } + if(e.port==80&&e.details.port_force!=='1'){e.porty=''}else{e.porty=':'+e.port} + e.url=e.protocol+'://'+e.authd+e.host+e.porty+e.path;return e.url; + break; + case'url_no_path': + e.authd=''; + if(!e.details.muser){e.details.muser=''} + if(!e.details.mpass){e.details.mpass=''} + if(e.details.muser!==''&&e.host.indexOf('@')===-1) { + e.authd=e.details.muser+':'+e.details.mpass+'@'; + } + if(e.port==80&&e.details.port_force!=='1'){e.porty=''}else{e.porty=':'+e.port} + e.url=e.protocol+'://'+e.authd+e.host+e.porty;return e.url; + break; + case'diskUsedEmit': + //send the amount used disk space to connected users + if(s.group[e.ke]&&s.group[e.ke].init){ + s.tx({f:'diskUsed',size:s.group[e.ke].usedSpace,limit:s.group[e.ke].sizeLimit},'GRP_'+e.ke); + } + break; + case'diskUsedSet': + //`k` will be used as the value to add or substract + s.group[e.ke].sizeChangeQueue.push(k) + if(s.group[e.ke].sizeChanging!==true){ + //lock this function + s.group[e.ke].sizeChanging=true + //validate current values + if(!s.group[e.ke].usedSpace){ + s.group[e.ke].usedSpace=0 + }else{ + s.group[e.ke].usedSpace=parseFloat(s.group[e.ke].usedSpace) + } + if(s.group[e.ke].usedSpace<0||isNaN(s.group[e.ke].usedSpace)){ + s.group[e.ke].usedSpace=0 + } + //set queue processor + var checkQueue=function(){ + //get first in queue + var currentChange = s.group[e.ke].sizeChangeQueue[0] + //change global size value + s.group[e.ke].usedSpace=s.group[e.ke].usedSpace+currentChange + //remove value just used from queue + s.group[e.ke].sizeChangeQueue = s.group[e.ke].sizeChangeQueue.splice(1,s.group[e.ke].sizeChangeQueue.length+10) + //do next one + if(s.group[e.ke].sizeChangeQueue.length>0){ + checkQueue() + }else{ + s.group[e.ke].sizeChanging=false + s.init('diskUsedEmit',e) + } + } + checkQueue() + } + break; + } + if(typeof e.callback==='function'){setTimeout(function(){e.callback()},500);} +} +s.filterEvents=function(x,d){ + switch(x){ + case'archive': + d.videos.forEach(function(v,n){ + s.video('archive',v) + }) + break; + case'email': + if(d.videos&&d.videos.length>0){ + d.videos.forEach(function(v,n){ + + }) + d.mailOptions = { + from: '"ShinobiCCTV" ', // sender address + to: d.mail, // list of receivers + subject: lang['Filter Matches']+' : '+d.name, // Subject line + html: lang.FilterMatchesText1+' '+d.videos.length+' '+lang.FilterMatchesText2, + }; + if(d.execute&&d.execute!==''){ + d.mailOptions.html+='
'+lang.Executed+' : '+d.execute+'
' + } + if(d.delete==='1'){ + d.mailOptions.html+='
'+lang.Deleted+' : '+lang.Yes+'
' + } + d.mailOptions.html+='
'+lang.Query+' : '+d.query+'
' + d.mailOptions.html+='
'+lang['Filter ID']+' : '+d.id+'
' + nodemailer.sendMail(d.mailOptions, (error, info) => { + if (error) { + s.tx({f:'error',ff:'filter_mail',ke:d.ke,error:error},'GRP_'+d.ke); + return ; + } + s.tx({f:'filter_mail',ke:d.ke,info:info},'GRP_'+d.ke); + }); + } + break; + case'delete': + d.videos.forEach(function(v,n){ + s.video('delete',v) + }) + break; + case'execute': + exec(d.execute,{detached: true}) + break; + } +} +s.video=function(x,e,k){ + if(!e){e={}}; + switch(x){ + case'getDir': + if(e.mid&&!e.id){e.id=e.mid}; + if(e.details&&(e.details instanceof Object)===false){ + try{e.details=JSON.parse(e.details)}catch(err){} + } + if(e.details&&e.details.dir&&e.details.dir!==''){ + return s.checkCorrectPathEnding(e.details.dir)+e.ke+'/'+e.id+'/' + }else{ + return s.dir.videos+e.ke+'/'+e.id+'/'; + } + break; + } + if(!k)k={}; + if(x!=='getDir'){e.dir=s.video('getDir',e)} + switch(x){ + case'fix': + e.sdir=s.dir.streams+e.ke+'/'+e.id+'/'; + if(!e.filename&&e.time){e.filename=s.formattedTime(e.time)} + if(e.filename.indexOf('.')===-1){ + e.filename=e.filename+'.'+e.ext + } + s.tx({f:'video_fix_start',mid:e.mid,ke:e.ke,filename:e.filename},'GRP_'+e.ke) + s.group[e.ke].mon[e.id].fixingVideos[e.filename]={} + switch(e.ext){ + case'mp4': + e.fixFlags='-vcodec libx264 -acodec aac -strict -2'; + break; + case'webm': + e.fixFlags='-vcodec libvpx -acodec libvorbis'; + break; + } + e.spawn=spawn(config.ffmpegDir,('-i '+e.dir+e.filename+' '+e.fixFlags+' '+e.sdir+e.filename).split(' '),{detached: true}) + e.spawn.stdout.on('data',function(data){ + s.tx({f:'video_fix_data',mid:e.mid,ke:e.ke,filename:e.filename},'GRP_'+e.ke) + }); + e.spawn.on('close',function(data){ + exec('mv '+e.dir+e.filename+' '+e.sdir+e.filename,{detached: true}).on('exit',function(){ + s.tx({f:'video_fix_success',mid:e.mid,ke:e.ke,filename:e.filename},'GRP_'+e.ke) + delete(s.group[e.ke].mon[e.id].fixingVideos[e.filename]); + }) + }); + break; + case'archive': + if(!e.filename&&e.time){e.filename=s.formattedTime(e.time)} + if(!e.status){e.status=0} + e.details.archived="1" + e.save=[JSON.stringify(e.details),e.id,e.ke,s.nameToTime(e.filename)]; + s.sqlQuery('UPDATE Videos SET details=? WHERE `mid`=? AND `ke`=? AND `time`=?',e.save,function(err,r){ + s.tx({f:'video_edit',status:3,filename:e.filename+'.'+e.ext,mid:e.mid,ke:e.ke,time:s.nameToTime(e.filename)},'GRP_'+e.ke); + }); + break; + case'delete': + if(!e.filename&&e.time){e.filename=s.formattedTime(e.time)} + var filename + if(e.filename.indexOf('.')>-1){ + filename = e.filename + }else{ + filename = e.filename+'.'+e.ext + } + if(!e.status){e.status=0} + e.save=[e.id,e.ke,s.nameToTime(filename)]; + s.sqlQuery('SELECT * FROM Videos WHERE `mid`=? AND `ke`=? AND `time`=?',e.save,function(err,r){ + if(r&&r[0]){ + r=r[0] + var dir=s.video('getDir',r) + s.sqlQuery('DELETE FROM Videos WHERE `mid`=? AND `ke`=? AND `time`=?',e.save,function(){ + fs.stat(dir+filename,function(err,file){ + if(err){ + s.systemLog('File Delete Error : '+e.ke+' : '+' : '+e.mid,err) + } + s.init('diskUsedSet',e,-(r.size/1000000)) + }) + s.tx({f:'video_delete',filename:filename,mid:e.mid,ke:e.ke,time:s.nameToTime(filename),end:s.formattedTime(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke); + s.file('delete',dir+filename) + }) + } + }) + break; +// case'open': +// //on video open +// e.save=[e.id,e.ke,s.nameToTime(e.filename),e.ext]; +// if(!e.status){e.save.push(0)}else{e.save.push(e.status)} +// k.details={} +// if(e.details&&e.details.dir&&e.details.dir!==''){ +// k.details.dir=e.details.dir +// } +// e.save.push(s.s(k.details)) +// s.sqlQuery('INSERT INTO Videos (mid,ke,time,ext,status,details) VALUES (?,?,?,?,?,?)',e.save) +// s.tx({f:'video_build_start',filename:e.filename+'.'+e.ext,mid:e.id,ke:e.ke,time:s.nameToTime(e.filename),end:s.formattedTime(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke); +// break; +// case'close': +// //video function : close +// if(s.group[e.ke]&&s.group[e.ke].mon[e.id]){ +// if(s.group[e.ke].mon[e.id].open&&!e.filename){ +// e.filename=s.group[e.ke].mon[e.id].open; +// e.ext=s.group[e.ke].mon[e.id].open_ext +// } +// if(s.group[e.ke].mon[e.id].childNode){ +// s.cx({f:'close',d:s.init('noReference',e)},s.group[e.ke].mon[e.id].childNodeId); +// }else{ +// k.file = e.filename+'.'+e.ext +// k.dir = e.dir.toString() +// //get file directory +// k.fileExists = fs.existsSync(k.dir+k.file) +// if(k.fileExists!==true){ +// k.dir=s.dir.videos+'/'+e.ke+'/'+e.id+'/' +// k.fileExists=fs.existsSync(k.dir+k.file) +// if(k.fileExists!==true){ +// s.dir.addStorage.forEach(function(v){ +// if(k.fileExists!==true){ +// k.dir=s.checkCorrectPathEnding(v.path)+e.ke+'/'+e.id+'/' +// k.fileExists=fs.existsSync(k.dir+k.file) +// } +// }) +// } +// } +// if(k.fileExists===true){ +// //close video row +// k.stat = fs.statSync(k.dir+k.file) +// e.filesize = k.stat.size +// e.filesizeMB = parseFloat((e.filesize/1000000).toFixed(2)) +// e.end_time = s.formattedTime(k.stat.mtime,'YYYY-MM-DD HH:mm:ss') +// var save = [ +// e.filesize, +// 1, +// e.end_time, +// e.id, +// e.ke, +// s.nameToTime(e.filename) +// ] +// if(!e.status){ +// save.push(0) +// }else{ +// save.push(e.status) +// } +// s.sqlQuery('UPDATE Videos SET `size`=?,`status`=?,`end`=? WHERE `mid`=? AND `ke`=? AND `time`=? AND `status`=?',save) +// //send event for completed recording +// s.txWithSubPermissions({ +// f:'video_build_success', +// hrefNoAuth:'/videos/'+e.ke+'/'+e.mid+'/'+k.file, +// filename:k.file, +// mid:e.id, +// ke:e.ke, +// time:s.timeObject(s.nameToTime(e.filename)).format(), +// size:e.filesize, +// end:s.timeObject(e.end_time).format() +// },'GRP_'+e.ke,'video_view'); +// //send new diskUsage values +// s.video('diskUseUpdate',e,k) +// }else{ +// s.video('delete',e); +// s.log(e,{type:lang['File Not Exist'],msg:lang.FileNotExistText,ffmpeg:s.group[e.ke].mon[e.id].ffmpeg}) +// if(e.mode && config.restart.onVideoNotExist === true){ +// delete(s.group[e.ke].mon[e.id].open); +// s.log(e,{ +// type : lang['Camera is not recording'], +// msg : { +// msg : lang.CameraNotRecordingText +// } +// }); +// if(s.group[e.ke].mon[e.id].started===1){ +// s.camera('restart',e) +// } +// } +// } +// } +// } +// delete(s.group[e.ke].mon[e.id].open); +// break; + case'linkBuild': + //e = video rows + //k = auth key + e.forEach(function(v){ + var details = JSON.parse(v.details) + var queryString = [] + if(details.isUTC === true){ + queryString.push('isUTC=true') + }else{ + v.time = s.utcToLocal(v.time) + v.end = s.utcToLocal(v.end) + } + if(queryString.length > 0){ + queryString = '?'+queryString.join('&') + }else{ + queryString = '' + } + v.href = '/'+k+'/videos/'+v.ke+'/'+v.mid+'/'+s.formattedTime(v.time)+'.'+v.ext; + v.links = { + deleteVideo : v.href+'/delete' + queryString, + changeToUnread : v.href+'/status/1' + queryString, + changeToRead : v.href+'/status/2' + queryString + } + v.href = v.href + queryString + v.details = details + }) + break; + case'diskUseUpdate': + if(s.group[e.ke].init){ + s.init('diskUsedSet',e,e.filesizeMB) + if(config.cron.deleteOverMax===true){ + //check space + s.group[e.ke].sizePurgeQueue.push(1) + if(s.group[e.ke].sizePurging!==true){ + //lock this function + s.group[e.ke].sizePurging=true + //set queue processor + var finish=function(){ + //remove value just used from queue + s.group[e.ke].sizePurgeQueue = s.group[e.ke].sizePurgeQueue.splice(1,s.group[e.ke].sizePurgeQueue.length+10) + //do next one + if(s.group[e.ke].sizePurgeQueue.length>0){ + checkQueue() + }else{ + s.group[e.ke].sizePurging=false + s.init('diskUsedEmit',e) + } + } + var checkQueue=function(){ + //get first in queue + var currentPurge = s.group[e.ke].sizePurgeQueue[0] + var deleteVideos = function(){ + //run purge command + if(s.group[e.ke].usedSpace>(s.group[e.ke].sizeLimit*config.cron.deleteOverMaxOffset)){ + s.sqlQuery('SELECT * FROM Videos WHERE status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND ke=? ORDER BY `time` ASC LIMIT 2',[e.ke],function(err,evs){ + k.del=[];k.ar=[e.ke]; + if(!evs)return console.log(err) + evs.forEach(function(ev){ + ev.dir=s.video('getDir',ev)+s.formattedTime(ev.time)+'.'+ev.ext; + k.del.push('(mid=? AND time=?)'); + k.ar.push(ev.mid),k.ar.push(ev.time); + s.file('delete',ev.dir); + s.init('diskUsedSet',e,-(ev.size/1000000)) + s.tx({f:'video_delete',ff:'over_max',filename:s.formattedTime(ev.time)+'.'+ev.ext,mid:ev.mid,ke:ev.ke,time:ev.time,end:s.formattedTime(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke); + }); + if(k.del.length>0){ + k.qu=k.del.join(' OR '); + s.sqlQuery('DELETE FROM Videos WHERE ke =? AND ('+k.qu+')',k.ar,function(){ + deleteVideos() + }) + }else{ + finish() + } + }) + }else{ + finish() + } + } + deleteVideos() + } + checkQueue() + } + }else{ + s.init('diskUsedEmit',e) + } + } + break; + case'insertCompleted': + k.dir = e.dir.toString() + if(s.group[e.ke].mon[e.id].childNode){ + s.cx({f:'insertCompleted',d:s.group[e.ke].mon_conf[e.id],k:k},s.group[e.ke].mon[e.id].childNodeId); + }else{ + //get file directory + k.fileExists = fs.existsSync(k.dir+k.file) + if(k.fileExists!==true){ + k.dir = s.dir.videos+'/'+e.ke+'/'+e.id+'/' + k.fileExists = fs.existsSync(k.dir+k.file) + if(k.fileExists !== true){ + s.dir.addStorage.forEach(function(v){ + if(k.fileExists !== true){ + k.dir = s.checkCorrectPathEnding(v.path)+e.ke+'/'+e.id+'/' + k.fileExists = fs.existsSync(k.dir+k.file) + } + }) + } + } + if(k.fileExists===true){ + //close video row + k.stat = fs.statSync(k.dir+k.file) + e.filesize = k.stat.size + e.filesizeMB = parseFloat((e.filesize/1000000).toFixed(2)) + + e.startTime = new Date(s.nameToTime(k.file)) + e.endTime = new Date(k.stat.mtime) + if(config.useUTC === true){ + fs.rename(k.dir+k.file, k.dir+s.formattedTime(e.startTime)+'.'+e.ext, (err) => { + if (err) return console.error(err); + }); + k.filename = s.formattedTime(e.startTime)+'.'+e.ext + }else{ + e.startTime = s.utcToLocal(e.startTime) + e.endTime = s.utcToLocal(e.endTime) + k.filename = k.file + } + if(!e.ext){e.ext = k.filename.split('.')[1]} + //send event for completed recording + if(config.childNodes.enabled === true && config.childNodes.mode === 'child' && config.childNodes.host){ + fs.createReadStream(k.dir+k.filename) + .on('data',function(data){ + s.cx({ + f:'created_file_chunk', + mid:e.id, + ke:e.ke, + chunk:data, + filename:k.filename, + d:s.init('noReference',e), + filesize:e.filesize, + time:s.timeObject(e.startTime).format(), + end:s.timeObject(e.endTime).format() + }) + }) + .on('close',function(){ + clearTimeout(s.group[e.ke].mon[e.id].checker) + clearTimeout(s.group[e.ke].mon[e.id].checkStream) + s.cx({ + f:'created_file', + mid:e.id, + ke:e.ke, + filename:k.filename, + d:s.init('noReference',e), + filesize:e.filesize, + time:s.timeObject(e.startTime).format(), + end:s.timeObject(e.endTime).format() + }) + }); + }else{ + var href = '/videos/'+e.ke+'/'+e.mid+'/'+k.filename + if(config.useUTC === true)href += '?isUTC=true'; + s.txWithSubPermissions({ + f:'video_build_success', + hrefNoAuth:href, + filename:k.filename, + mid:e.mid, + ke:e.ke, + time:s.timeObject(e.startTime).format(), + size:e.filesize, + end:s.timeObject(e.endTime).format() + },'GRP_'+e.ke,'video_view'); + } + //cloud auto savers + //webdav + // var webDAV = s.group[e.ke].webdav + // if(webDAV&&s.group[e.ke].init.use_webdav!=='0'&&s.group[e.ke].init.webdav_save=="1"){ + // fs.readFile(k.dir+k.filename,function(err,data){ + // var webdavUploadDir = s.group[e.ke].init.webdav_dir+e.ke+'/'+e.mid+'/' + // fs.readFile(k.dir+k.filename,function(err,data){ + // webDAV.putFileContents(webdavUploadDir+k.filename,"binary",data).catch(function(err) { + // if(err){ + // webDAV.createDirectory(webdavUploadDir).catch(function(err) { + // s.log(e,{type:lang['Webdav Error'],msg:{msg:lang.WebdavErrorText+' /'+webdavUploadDir+'',info:err}}) + // }) + // webDAV.putFileContents(webdavUploadDir+k.filename,"binary",data).catch(function(err) { + // s.log(e,{type:lang['Webdav Error'],msg:{msg:lang.WebdavErrorText+' /'+webdavUploadDir+'',info:err}}) + // }) + // s.log(e,{type:lang['Webdav Error'],msg:{msg:lang.WebdavErrorText+' /'+webdavUploadDir+'',info:err}}) + // } + // }); + // }); + // }); + // } + if(s.group[e.ke].webdav&&s.group[e.ke].init.use_webdav!=='0'&&s.group[e.ke].init.webdav_save=="1"){ + fs.readFile(k.dir+k.filename,function(err,data){ + s.group[e.ke].webdav.putFileContents(s.group[e.ke].init.webdav_dir+e.ke+'/'+e.mid+'/'+k.filename,"binary",data) + .catch(function(err) { + s.log(e,{type:lang['Webdav Error'],msg:{msg:lang.WebdavErrorText+' /'+e.ke+'/'+e.id+'',info:err},ffmpeg:s.group[e.ke].mon[e.id].ffmpeg}) + console.error(err); + }); + }); + } + k.details = {} + if(e.details&&e.details.dir&&e.details.dir!==''){ + k.details.dir = e.details.dir + } + if(config.useUTC)k.details.isUTC = config.useUTC; + var save = [ + e.mid, + e.ke, + e.startTime, + e.ext, + 1, + s.s(k.details), + e.filesize, + e.endTime, + ] + s.sqlQuery('INSERT INTO Videos (mid,ke,time,ext,status,details,size,end) VALUES (?,?,?,?,?,?,?,?)',save) + //send new diskUsage values + s.video('diskUseUpdate',e,k) + } + } + break; + } +} +s.splitForFFPMEG = function (ffmpegCommandAsString) { + //this function ignores spaces inside quotes. + return ffmpegCommandAsString.match(/\\?.|^$/g).reduce((p, c) => { + if(c === '"'){ + p.quote ^= 1; + }else if(!p.quote && c === ' '){ + p.a.push(''); + }else{ + p.a[p.a.length-1] += c.replace(/\\(.)/,"$1"); + } + return p; + }, {a: ['']}).a +}; +s.ffmpeg=function(e){ + //create input map + var createFFmpegMap = function(arrayOfMaps){ + //e.details.input_map_choices.stream + var string = ''; + if(e.details.input_maps && e.details.input_maps.length > 0){ + if(arrayOfMaps && arrayOfMaps instanceof Array && arrayOfMaps.length>0){ + arrayOfMaps.forEach(function(v){ + if(v.map==='')v.map='0' + string += ' -map '+v.map + }) + }else{ + string += ' -map 0:0' + } + } + return string; + } + var createInputMap = function(number,input){ + //fulladdress - Full Input Path + //`x` is an object used to contain temporary values. + var x = {} + x.cust_input = '' + x.hwaccel = '' + if(input.cust_input&&input.cust_input!==''){x.cust_input+=' '+input.cust_input;} + //input - analyze duration + if(input.aduration&&input.aduration!==''){x.cust_input+=' -analyzeduration '+input.aduration}; + //input - probe size + if(input.probesize&&input.probesize!==''){x.cust_input+=' -probesize '+input.probesize}; + //input - stream loop (good for static files/lists) + if(input.stream_loop==='1'){x.cust_input+=' -stream_loop -1'}; + //input - fps + if(x.cust_input.indexOf('-r ')===-1&&input.sfps&&input.sfps!==''){ + input.sfps=parseFloat(input.sfps); + if(isNaN(input.sfps)){input.sfps=1} + x.cust_input+=' -r '+input.sfps + } + //input - is mjpeg + if(input.type==='mjpeg'){ + if(x.cust_input.indexOf('-f ')===-1){ + x.cust_input+=' -f mjpeg' + } + //input - frames per second + x.cust_input+=' -reconnect 1'; + }else + //input - is h264 has rtsp in address and transport method is chosen + if((input.type==='h264'||input.type==='mp4')&&input.fulladdress.indexOf('rtsp://')>-1&&input.rtsp_transport!==''&&input.rtsp_transport!=='no'){ + x.cust_input += ' -rtsp_transport '+input.rtsp_transport; + }else + if((input.type==='mp4'||input.type==='mjpeg')&&x.cust_input.indexOf('-re')===-1){ + x.cust_input += ' -re' + } + //hardware acceleration + if(input.accelerator&&input.accelerator==='1'){ + if(input.hwaccel&&input.hwaccel!==''){ + x.hwaccel+=' -hwaccel '+input.hwaccel; + } + if(input.hwaccel_vcodec&&input.hwaccel_vcodec!==''&&input.hwaccel_vcodec!=='auto'&&input.hwaccel_vcodec!=='no'){ + x.hwaccel+=' -c:v '+input.hwaccel_vcodec; + } + if(input.hwaccel_device&&input.hwaccel_device!==''){ + switch(input.hwaccel){ + case'vaapi': + x.hwaccel+=' -vaapi_device '+input.hwaccel_device+' -hwaccel_output_format vaapi'; + break; + default: + x.hwaccel+=' -hwaccel_device '+input.hwaccel_device; + break; + } + } + } + //custom - input flags + return x.hwaccel+x.cust_input+' -i "'+input.fulladdress+'"'; + } + //create sub stream channel + var createStreamChannel = function(number,channel){ + //`x` is an object used to contain temporary values. + var x = { + pipe:'' + } + if(!number||number==''){ + x.channel_sdir = e.sdir; + }else{ + x.channel_sdir = e.sdir+'channel'+number+'/'; + if (!fs.existsSync(x.channel_sdir)){ + fs.mkdirSync(x.channel_sdir); + } + } + x.stream_video_filters=[] + //stream - frames per second + if(channel.stream_vcodec!=='copy'){ + if(!channel.stream_fps||channel.stream_fps===''){ + switch(channel.stream_type){ + case'rtmp': + channel.stream_fps=30 + break; + default: +// channel.stream_fps=5 + break; + } + } + } + if(channel.stream_fps&&channel.stream_fps!==''){x.stream_fps=' -r '+channel.stream_fps}else{x.stream_fps=''} + + //stream - hls vcodec + if(channel.stream_vcodec&&channel.stream_vcodec!=='no'){ + if(channel.stream_vcodec!==''){x.stream_vcodec=' -c:v '+channel.stream_vcodec}else{x.stream_vcodec=' -c:v libx264'} + }else{ + x.stream_vcodec=''; + } + //stream - hls acodec + if(channel.stream_acodec!=='no'){ + if(channel.stream_acodec&&channel.stream_acodec!==''){x.stream_acodec=' -c:a '+channel.stream_acodec}else{x.stream_acodec=''} + }else{ + x.stream_acodec=' -an'; + } + //stream - resolution + if(channel.stream_scale_x&&channel.stream_scale_x!==''&&channel.stream_scale_y&&channel.stream_scale_y!==''){ + x.dimensions = channel.stream_scale_x+'x'+channel.stream_scale_y; + } + //stream - hls segment time + if(channel.hls_time&&channel.hls_time!==''){x.hls_time=channel.hls_time}else{x.hls_time="2"} + //hls list size + if(channel.hls_list_size&&channel.hls_list_size!==''){x.hls_list_size=channel.hls_list_size}else{x.hls_list_size=2} + //stream - custom flags + if(channel.cust_stream&&channel.cust_stream!==''){x.cust_stream=' '+channel.cust_stream}else{x.cust_stream=''} + //stream - preset + if(channel.preset_stream&&channel.preset_stream!==''){x.preset_stream=' -preset '+channel.preset_stream;}else{x.preset_stream=''} + //hardware acceleration + if(e.details.accelerator&&e.details.accelerator==='1'){ + if(e.details.hwaccel&&e.details.hwaccel!==''){ + x.hwaccel+=' -hwaccel '+e.details.hwaccel; + } + if(e.details.hwaccel_vcodec&&e.details.hwaccel_vcodec!==''){ + x.hwaccel+=' -c:v '+e.details.hwaccel_vcodec; + } + if(e.details.hwaccel_device&&e.details.hwaccel_device!==''){ + switch(e.details.hwaccel){ + case'vaapi': + x.hwaccel+=' -vaapi_device '+e.details.hwaccel_device+' -hwaccel_output_format vaapi'; + break; + default: + x.hwaccel+=' -hwaccel_device '+e.details.hwaccel_device; + break; + } + } + // else{ + // if(e.details.hwaccel==='vaapi'){ + // x.hwaccel+=' -hwaccel_device 0'; + // } + // } + } + + if(channel.rotate_stream&&channel.rotate_stream!==""&&channel.rotate_stream!=="no"){ + x.stream_video_filters.push('transpose='+channel.rotate_stream); + } + //stream - video filter + if(channel.svf&&channel.svf!==''){ + x.stream_video_filters.push(channel.svf) + } + if(x.stream_video_filters.length>0){ + var string = x.stream_video_filters.join(',').trim() + if(string===''){ + x.stream_video_filters='' + }else{ + x.stream_video_filters=' -vf '+string + } + }else{ + x.stream_video_filters='' + } + if(e.details.input_map_choices&&e.details.input_map_choices.record){ + //add input feed map + x.pipe += createFFmpegMap(e.details.input_map_choices['stream_channel-'+(number-config.pipeAddition)]) + } + if(channel.stream_vcodec!=='copy'){ + x.cust_stream+=x.stream_fps + } + switch(channel.stream_type){ + case'mp4': + x.cust_stream+=' -movflags +frag_keyframe+empty_moov+default_base_moof -metadata title="Poseidon Stream" -reset_timestamps 1' + if(channel.stream_vcodec!=='copy'){ + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + if(channel.stream_quality && channel.stream_quality !== '')x.cust_stream+=' -crf '+channel.stream_quality; + x.cust_stream+=x.preset_stream + x.cust_stream+=x.stream_video_filters + } + x.pipe+=' -f mp4'+x.stream_acodec+x.stream_vcodec+x.cust_stream+' pipe:'+number; + break; + case'rtmp': + x.rtmp_server_url=s.checkCorrectPathEnding(channel.rtmp_server_url); + if(channel.stream_vcodec!=='copy'){ + if(channel.stream_vcodec==='libx264'){ + channel.stream_vcodec = 'h264' + } + if(channel.stream_quality && channel.stream_quality !== '')x.cust_stream+=' -crf '+channel.stream_quality; + x.cust_stream+=x.preset_stream + if(channel.stream_v_br&&channel.stream_v_br!==''){x.cust_stream+=' -b:v '+channel.stream_v_br} + } + if(channel.stream_vcodec!=='no'&&channel.stream_vcodec!==''){ + x.cust_stream+=' -vcodec '+channel.stream_vcodec + } + if(channel.stream_acodec!=='copy'){ + if(!channel.stream_acodec||channel.stream_acodec===''||channel.stream_acodec==='no'){ + channel.stream_acodec = 'aac' + } + if(!channel.stream_a_br||channel.stream_a_br===''){channel.stream_a_br='128k'} + x.cust_stream+=' -ab '+channel.stream_a_br + } + if(channel.stream_acodec!==''){ + x.cust_stream+=' -acodec '+channel.stream_acodec + } + x.pipe+=' -f flv'+x.stream_video_filters+x.cust_stream+' "'+x.rtmp_server_url+channel.rtmp_stream_key+'"'; + break; + case'h264': + if(channel.stream_vcodec!=='copy'){ + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + if(channel.stream_quality && channel.stream_quality !== '')x.cust_stream+=' -crf '+channel.stream_quality; + x.cust_stream+=x.preset_stream + x.cust_stream+=x.stream_video_filters + } + x.pipe+=' -f mpegts'+x.stream_acodec+x.stream_vcodec+x.cust_stream+' pipe:'+number; + break; + case'flv': + if(channel.stream_vcodec!=='copy'){ + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + if(channel.stream_quality && channel.stream_quality !== '')x.cust_stream+=' -crf '+channel.stream_quality; + x.cust_stream+=x.preset_stream + x.cust_stream+=x.stream_video_filters + } + x.pipe+=' -f flv'+x.stream_acodec+x.stream_vcodec+x.cust_stream+' pipe:'+number; + break; + case'hls': + if(channel.stream_vcodec!=='h264_vaapi'&&channel.stream_vcodec!=='copy'){ + if(channel.stream_quality && channel.stream_quality !== '')x.cust_stream+=' -crf '+channel.stream_quality; + if(x.cust_stream.indexOf('-tune')===-1){x.cust_stream+=' -tune zerolatency'} + if(x.cust_stream.indexOf('-g ')===-1){x.cust_stream+=' -g 1'} + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + x.cust_stream+=x.stream_video_filters + } + x.pipe+=x.preset_stream+x.stream_acodec+x.stream_vcodec+' -f hls'+x.cust_stream+' -hls_time '+x.hls_time+' -hls_list_size '+x.hls_list_size+' -start_number 0 -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist "'+x.channel_sdir+'s.m3u8"'; + break; + case'mjpeg': + if(channel.stream_quality && channel.stream_quality !== '')x.cust_stream+=' -q:v '+channel.stream_quality; + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + x.pipe+=' -c:v mjpeg -f mpjpeg -boundary_tag shinobi'+x.cust_stream+x.stream_video_filters+' pipe:'+number; + break; + default: + x.pipe='' + break; + } + return x.pipe + } + //set X for temporary values so we don't break our main monitor object. + var x={tmp:''}; + //set some placeholding values to avoid "undefined" in ffmpeg string. + x.record_string='' + x.cust_input='' + x.cust_detect=' ' + x.record_video_filters=[] + x.stream_video_filters=[] + x.hwaccel='' + x.pipe='' + //input - frame rate (capture rate) + if(e.details.sfps && e.details.sfps!==''){x.input_fps=' -r '+e.details.sfps}else{x.input_fps=''} + //input - analyze duration + if(e.details.aduration&&e.details.aduration!==''){x.cust_input+=' -analyzeduration '+e.details.aduration}; + //input - probe size + if(e.details.probesize&&e.details.probesize!==''){x.cust_input+=' -probesize '+e.details.probesize}; + //input - stream loop (good for static files/lists) + if(e.details.stream_loop==='1'){x.cust_input+=' -stream_loop -1'}; + //input + switch(e.type){ + case'h264': + switch(e.protocol){ + case'rtsp': + if(e.details.cust_input.indexOf('-fflags') === -1){x.cust_input+=' -fflags +igndts'} + if(e.details.rtsp_transport&&e.details.rtsp_transport!==''&&e.details.rtsp_transport!=='no'){x.cust_input+=' -rtsp_transport '+e.details.rtsp_transport;} + break; + } + break; + } + //record - resolution + if(e.width!==''&&e.height!==''&&!isNaN(e.width)&&!isNaN(e.height)){ + x.record_dimensions=' -s '+e.width+'x'+e.height + }else{ + x.record_dimensions='' + } + if(e.details.stream_scale_x&&e.details.stream_scale_x!==''&&e.details.stream_scale_y&&e.details.stream_scale_y!==''){ + x.dimensions = e.details.stream_scale_x+'x'+e.details.stream_scale_y; + } + //record - segmenting + x.segment=' -f segment -segment_atclocktime 1 -reset_timestamps 1 -strftime 1 -segment_list pipe:2 -segment_time '+(60*e.cutoff)+' "'+e.dir+'%Y-%m-%dT%H-%M-%S.'+e.ext+'"'; + //record - set defaults for extension, video quality + switch(e.ext){ + case'mp4': + x.vcodec='libx264';x.acodec='aac'; + if(e.details.crf&&e.details.crf!==''){x.vcodec+=' -crf '+e.details.crf} + break; + case'webm': + x.acodec='libvorbis',x.vcodec='libvpx'; + if(e.details.crf&&e.details.crf!==''){x.vcodec+=' -q:v '+e.details.crf}else{x.vcodec+=' -q:v 1';} + break; + } + if(e.details.vcodec==='h264_vaapi'){ + x.record_video_filters.push('format=nv12,hwupload'); + } + //record - use custom video codec + if(e.details.vcodec&&e.details.vcodec!==''&&e.details.vcodec!=='default'){x.vcodec=e.details.vcodec} + //record - use custom audio codec + if(e.details.acodec&&e.details.acodec!==''&&e.details.acodec!=='default'){x.acodec=e.details.acodec} + if(e.details.cust_record){ + if(x.acodec=='aac'&&e.details.cust_record.indexOf('-strict -2')===-1){e.details.cust_record+=' -strict -2';} + if(e.details.cust_record.indexOf('-threads')===-1){e.details.cust_record+=' -threads 1';} + } +// if(e.details.cust_input&&(e.details.cust_input.indexOf('-use_wallclock_as_timestamps 1')>-1)===false){e.details.cust_input+=' -use_wallclock_as_timestamps 1';} + //record - ready or reset codecs + if(x.acodec!=='no'){ + if(x.acodec.indexOf('none')>-1){x.acodec=''}else{x.acodec=' -acodec '+x.acodec} + }else{ + x.acodec=' -an' + } + if(x.vcodec.indexOf('none')>-1){x.vcodec=''}else{x.vcodec=' -vcodec '+x.vcodec} + //record - frames per second (fps) + if(e.fps&&e.fps!==''&&e.details.vcodec!=='copy'){x.record_fps=' -r '+e.fps}else{x.record_fps=''} + //stream - frames per second (fps) + if(e.details.stream_fps&&e.details.stream_fps!==''){x.stream_fps=' -r '+e.details.stream_fps}else{x.stream_fps=''} + //record - timestamp options for -vf + if(e.details.timestamp&&e.details.timestamp=="1"&&e.details.vcodec!=='copy'){ + //font + if(e.details.timestamp_font&&e.details.timestamp_font!==''){x.time_font=e.details.timestamp_font}else{x.time_font='/usr/share/fonts/truetype/freefont/FreeSans.ttf'} + //position x + if(e.details.timestamp_x&&e.details.timestamp_x!==''){x.timex=e.details.timestamp_x}else{x.timex='(w-tw)/2'} + //position y + if(e.details.timestamp_y&&e.details.timestamp_y!==''){x.timey=e.details.timestamp_y}else{x.timey='0'} + //text color + if(e.details.timestamp_color&&e.details.timestamp_color!==''){x.time_color=e.details.timestamp_color}else{x.time_color='white'} + //box color + if(e.details.timestamp_box_color&&e.details.timestamp_box_color!==''){x.time_box_color=e.details.timestamp_box_color}else{x.time_box_color='0x00000000@1'} + //text size + if(e.details.timestamp_font_size&&e.details.timestamp_font_size!==''){x.time_font_size=e.details.timestamp_font_size}else{x.time_font_size='10'} + + x.record_video_filters.push('drawtext=fontfile='+x.time_font+':text=\'%{localtime}\':x='+x.timex+':y='+x.timey+':fontcolor='+x.time_color+':box=1:boxcolor='+x.time_box_color+':fontsize='+x.time_font_size); + } + //record - watermark for -vf + if(e.details.watermark&&e.details.watermark=="1"&&e.details.watermark_location&&e.details.watermark_location!==''){ + switch(e.details.watermark_position){ + case'tl'://top left + x.watermark_position='10:10' + break; + case'tr'://top right + x.watermark_position='main_w-overlay_w-10:10' + break; + case'bl'://bottom left + x.watermark_position='10:main_h-overlay_h-10' + break; + default://bottom right + x.watermark_position='(main_w-overlay_w-10)/2:(main_h-overlay_h-10)/2' + break; + } + x.record_video_filters.push('movie='+e.details.watermark_location+'[watermark],[in][watermark]overlay='+x.watermark_position+'[out]'); + } + //record - rotation + if(e.details.rotate_record&&e.details.rotate_record!==""&&e.details.rotate_record!=="no"&&e.details.stream_vcodec!=="copy"){ + x.record_video_filters.push('transpose='+e.details.rotate_record); + } + //check custom record filters for -vf + if(e.details.vf&&e.details.vf!==''){ + x.record_video_filters.push(e.details.vf) + } + //compile filter string for -vf + if(x.record_video_filters.length>0){ + x.record_video_filters=' -vf '+x.record_video_filters.join(',') + }else{ + x.record_video_filters='' + } + //stream - timestamp + if(e.details.stream_timestamp&&e.details.stream_timestamp=="1"&&e.details.vcodec!=='copy'){ + //font + if(e.details.stream_timestamp_font&&e.details.stream_timestamp_font!==''){x.stream_timestamp_font=e.details.stream_timestamp_font}else{x.stream_timestamp_font='/usr/share/fonts/truetype/freefont/FreeSans.ttf'} + //position x + if(e.details.stream_timestamp_x&&e.details.stream_timestamp_x!==''){x.stream_timestamp_x=e.details.stream_timestamp_x}else{x.stream_timestamp_x='(w-tw)/2'} + //position y + if(e.details.stream_timestamp_y&&e.details.stream_timestamp_y!==''){x.stream_timestamp_y=e.details.stream_timestamp_y}else{x.stream_timestamp_y='0'} + //text color + if(e.details.stream_timestamp_color&&e.details.stream_timestamp_color!==''){x.stream_timestamp_color=e.details.stream_timestamp_color}else{x.stream_timestamp_color='white'} + //box color + if(e.details.stream_timestamp_box_color&&e.details.stream_timestamp_box_color!==''){x.stream_timestamp_box_color=e.details.stream_timestamp_box_color}else{x.stream_timestamp_box_color='0x00000000@1'} + //text size + if(e.details.stream_timestamp_font_size&&e.details.stream_timestamp_font_size!==''){x.stream_timestamp_font_size=e.details.stream_timestamp_font_size}else{x.stream_timestamp_font_size='10'} + + x.stream_video_filters.push('drawtext=fontfile='+x.stream_timestamp_font+':text=\'%{localtime}\':x='+x.stream_timestamp_x+':y='+x.stream_timestamp_y+':fontcolor='+x.stream_timestamp_color+':box=1:boxcolor='+x.stream_timestamp_box_color+':fontsize='+x.stream_timestamp_font_size); + } + //stream - watermark for -vf + if(e.details.stream_watermark&&e.details.stream_watermark=="1"&&e.details.stream_watermark_location&&e.details.stream_watermark_location!==''){ + switch(e.details.stream_watermark_position){ + case'tl'://top left + x.stream_watermark_position='10:10' + break; + case'tr'://top right + x.stream_watermark_position='main_w-overlay_w-10:10' + break; + case'bl'://bottom left + x.stream_watermark_position='10:main_h-overlay_h-10' + break; + default://bottom right + x.stream_watermark_position='(main_w-overlay_w-10)/2:(main_h-overlay_h-10)/2' + break; + } + x.stream_video_filters.push('movie='+e.details.stream_watermark_location+'[watermark],[in][watermark]overlay='+x.stream_watermark_position+'[out]'); + } + //stream - rotation + if(e.details.rotate_stream&&e.details.rotate_stream!==""&&e.details.rotate_stream!=="no"&&e.details.stream_vcodec!=='copy'){ + x.stream_video_filters.push('transpose='+e.details.rotate_stream); + } + //stream - hls vcodec + if(e.details.stream_vcodec&&e.details.stream_vcodec!=='no'){ + if(e.details.stream_vcodec!==''){x.stream_vcodec=' -c:v '+e.details.stream_vcodec}else{x.stream_vcodec=' -c:v libx264'} + }else{ + x.stream_vcodec=''; + } + //stream - hls acodec + if(e.details.stream_acodec!=='no'){ + if(e.details.stream_acodec&&e.details.stream_acodec!==''){x.stream_acodec=' -c:a '+e.details.stream_acodec}else{x.stream_acodec=''} + }else{ + x.stream_acodec=' -an'; + } + //stream - hls segment time + if(e.details.hls_time&&e.details.hls_time!==''){x.hls_time=e.details.hls_time}else{x.hls_time="2"} //hls list size + if(e.details.hls_list_size&&e.details.hls_list_size!==''){x.hls_list_size=e.details.hls_list_size}else{x.hls_list_size=2} + //stream - custom flags + if(e.details.cust_stream&&e.details.cust_stream!==''){x.cust_stream=' '+e.details.cust_stream}else{x.cust_stream=''} + //stream - preset + if(e.details.preset_stream&&e.details.preset_stream!==''){x.preset_stream=' -preset '+e.details.preset_stream;}else{x.preset_stream=''} + //stream - quality + //hardware acceleration + if(e.details.accelerator&&e.details.accelerator==='1'){ + if(e.details.hwaccel&&e.details.hwaccel!==''){ + x.hwaccel+=' -hwaccel '+e.details.hwaccel; + } + if(e.details.hwaccel_vcodec&&e.details.hwaccel_vcodec!==''){ + x.hwaccel+=' -c:v '+e.details.hwaccel_vcodec; + } + if(e.details.hwaccel_device&&e.details.hwaccel_device!==''){ + switch(e.details.hwaccel){ + case'vaapi': + x.hwaccel+=' -vaapi_device '+e.details.hwaccel_device; + break; + default: + x.hwaccel+=' -hwaccel_device '+e.details.hwaccel_device; + break; + } + } +// else{ +// if(e.details.hwaccel==='vaapi'){ +// x.hwaccel+=' -hwaccel_device 0'; +// } +// } + } + if(e.details.stream_vcodec==='h264_vaapi'){ + x.stream_video_filters=[] + x.stream_video_filters.push('format=nv12,hwupload'); + if(e.details.stream_scale_x&&e.details.stream_scale_x!==''&&e.details.stream_scale_y&&e.details.stream_scale_y!==''){ + x.stream_video_filters.push('scale_vaapi=w='+e.details.stream_scale_x+':h='+e.details.stream_scale_y) + } + } + //stream - video filter + if(e.details.svf&&e.details.svf!==''){ + x.stream_video_filters.push(e.details.svf) + } + if(x.stream_video_filters.length>0){ + x.stream_video_filters=' -vf '+x.stream_video_filters.join(',') + }else{ + x.stream_video_filters='' + } + //stream - pipe build + if(e.details.input_map_choices&&e.details.input_map_choices.stream){ + //add input feed map + x.pipe += createFFmpegMap(e.details.input_map_choices.stream) + } + if(e.details.stream_vcodec!=='copy'){ + x.cust_stream+=x.stream_fps + } + switch(e.details.stream_type){ + case'mp4': + x.cust_stream+=' -movflags +frag_keyframe+empty_moov+default_base_moof -metadata title="Poseidon Stream" -reset_timestamps 1' + if(e.details.stream_vcodec!=='copy'){ + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -crf '+e.details.stream_quality; + x.cust_stream+=x.preset_stream + x.cust_stream+=x.stream_video_filters + } + x.pipe+=' -f mp4'+x.stream_acodec+x.stream_vcodec+x.cust_stream+' pipe:1'; + break; + case'flv': + if(e.details.stream_vcodec!=='copy'){ + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -crf '+e.details.stream_quality; + x.cust_stream+=x.preset_stream + x.cust_stream+=x.stream_video_filters + } + x.pipe+=' -f flv'+x.stream_acodec+x.stream_vcodec+x.cust_stream+' pipe:1'; + break; + case'hls': + if(e.details.stream_vcodec!=='h264_vaapi'&&e.details.stream_vcodec!=='copy'){ + if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -crf '+e.details.stream_quality; + if(x.cust_stream.indexOf('-tune')===-1){x.cust_stream+=' -tune zerolatency'} + if(x.cust_stream.indexOf('-g ')===-1){x.cust_stream+=' -g 1'} + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + x.cust_stream+=x.stream_video_filters + } + x.pipe+=x.preset_stream+x.stream_acodec+x.stream_vcodec+' -f hls'+x.cust_stream+' -hls_time '+x.hls_time+' -hls_list_size '+x.hls_list_size+' -start_number 0 -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist "'+e.sdir+'s.m3u8"'; + break; + case'mjpeg': + if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -q:v '+e.details.stream_quality; + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + x.pipe+=' -an -c:v mjpeg -f mpjpeg -boundary_tag shinobi'+x.cust_stream+x.stream_video_filters+' pipe:1'; + break; + case'pam': + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -q:v '+e.details.stream_quality; + x.pipe+=' -an -c:v pam -pix_fmt rgba -f image2pipe'+x.cust_stream+x.stream_video_filters+' pipe:1'; + break; + case'b64':case'':case undefined:case null://base64 + if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -q:v '+e.details.stream_quality; + if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions} + x.pipe+=' -an -c:v mjpeg -f image2pipe'+x.cust_stream+x.stream_video_filters+' pipe:1'; + break; + default: + x.pipe='' + break; + } + if(e.details.stream_channels){ + e.details.stream_channels.forEach(function(v,n){ + x.pipe+=createStreamChannel(n+config.pipeAddition,v) + }) + } + //detector - plugins, motion + if(e.details.detector==='1'&&e.details.detector_send_frames==='1'){ + if(e.details.input_map_choices&&e.details.input_map_choices.detector){ + //add input feed map + x.pipe += createFFmpegMap(e.details.input_map_choices.detector) + } + if(!e.details.detector_fps||e.details.detector_fps===''){e.details.detector_fps=2} + if(e.details.detector_scale_x&&e.details.detector_scale_x!==''&&e.details.detector_scale_y&&e.details.detector_scale_y!==''){x.dratio=' -s '+e.details.detector_scale_x+'x'+e.details.detector_scale_y}else{x.dratio=' -s 320x240'} + if(e.details.cust_detect&&e.details.cust_detect!==''){x.cust_detect+=e.details.cust_detect;} + if(e.details.detector_pam==='1'){ + x.pipe+=' -an -c:v pam -pix_fmt gray -f image2pipe -vf fps='+e.details.detector_fps+x.cust_detect+x.dratio+' pipe:3' + if(e.details.detector_use_detect_object === '1'){ + //for object detection + x.pipe += createFFmpegMap(e.details.input_map_choices.detector) + x.pipe += ' -f singlejpeg -vf fps='+e.details.detector_fps+x.cust_detect+x.dratio+' pipe:4'; + } + }else{ + x.pipe+=' -f singlejpeg -vf fps='+e.details.detector_fps+x.cust_detect+x.dratio+' pipe:3'; + } + } + //api - snapshot bin/ cgi.bin (JPEG Mode) + if(e.details.snap==='1'){ + if(e.details.input_map_choices&&e.details.input_map_choices.snap){ + //add input feed map + x.pipe += createFFmpegMap(e.details.input_map_choices.snap) + } + if(!e.details.snap_fps||e.details.snap_fps===''){e.details.snap_fps=1} + if(e.details.snap_vf&&e.details.snap_vf!==''){x.snap_vf=' -vf '+e.details.snap_vf}else{x.snap_vf=''} + if(e.details.snap_scale_x&&e.details.snap_scale_x!==''&&e.details.snap_scale_y&&e.details.snap_scale_y!==''){x.snap_ratio=' -s '+e.details.snap_scale_x+'x'+e.details.snap_scale_y}else{x.snap_ratio=''} + if(e.details.cust_snap&&e.details.cust_snap!==''){x.cust_snap=' '+e.details.cust_snap;}else{x.cust_snap=''} + x.pipe+=' -update 1 -r '+e.details.snap_fps+x.cust_snap+x.snap_ratio+x.snap_vf+' "'+e.sdir+'s.jpg" -y'; + } + //Traditional Recording Buffer + if(e.details.detector=='1'&&e.details.detector_trigger=='1'&&e.details.detector_record_method==='sip'){ + if(e.details.input_map_choices&&e.details.input_map_choices.detector_sip_buffer){ + //add input feed map + x.pipe += createFFmpegMap(e.details.input_map_choices.detector_sip_buffer) + } + x.detector_buffer_filters=[] + if(!e.details.detector_buffer_vcodec||e.details.detector_buffer_vcodec===''||e.details.detector_buffer_vcodec==='auto'){ + switch(e.type){ + case'h264':case'hls':case'mp4': + e.details.detector_buffer_vcodec = 'copy' + break; + default: + e.details.detector_buffer_vcodec = 'libx264' + break; + } + } + if(!e.details.detector_buffer_acodec||e.details.detector_buffer_acodec===''||e.details.detector_buffer_acodec==='auto'){ + switch(e.type){ + case'h264':case'hls':case'mp4': + e.details.detector_buffer_acodec = 'copy' + break; + default: + e.details.detector_buffer_acodec = 'aac' + break; + } + } + if(e.details.detector_buffer_acodec === 'no'){ + x.detector_buffer_acodec = ' -an' + }else{ + x.detector_buffer_acodec = ' -c:a '+e.details.detector_buffer_acodec + } + if(!e.details.detector_buffer_tune||e.details.detector_buffer_tune===''){e.details.detector_buffer_tune='zerolatency'} + if(!e.details.detector_buffer_g||e.details.detector_buffer_g===''){e.details.detector_buffer_g='1'} + if(!e.details.detector_buffer_hls_time||e.details.detector_buffer_hls_time===''){e.details.detector_buffer_hls_time='2'} + if(!e.details.detector_buffer_hls_list_size||e.details.detector_buffer_hls_list_size===''){e.details.detector_buffer_hls_list_size='4'} + if(!e.details.detector_buffer_start_number||e.details.detector_buffer_start_number===''){e.details.detector_buffer_start_number='0'} + if(!e.details.detector_buffer_live_start_index||e.details.detector_buffer_live_start_index===''){e.details.detector_buffer_live_start_index='-3'} + + if(e.details.detector_buffer_vcodec.indexOf('_vaapi')>-1){ + if(x.hwaccel.indexOf('-vaapi_device')>-1){ + x.detector_buffer_filters.push('format=nv12') + x.detector_buffer_filters.push('hwupload') + }else{ + e.details.detector_buffer_vcodec='libx264' + } + } + if(e.details.detector_buffer_vcodec!=='copy'){ + if(e.details.detector_buffer_fps&&e.details.detector_buffer_fps!==''){ + x.detector_buffer_fps=' -r '+e.details.detector_buffer_fps + }else{ + x.detector_buffer_fps=' -r 30' + } + }else{ + x.detector_buffer_fps='' + } + if(x.detector_buffer_filters.length>0){ + x.pipe+=' -vf '+x.detector_buffer_filters.join(',') + } + x.pipe+=x.detector_buffer_fps+x.detector_buffer_acodec+' -c:v '+e.details.detector_buffer_vcodec+' -f hls -tune '+e.details.detector_buffer_tune+' -g '+e.details.detector_buffer_g+' -hls_time '+e.details.detector_buffer_hls_time+' -hls_list_size '+e.details.detector_buffer_hls_list_size+' -start_number '+e.details.detector_buffer_start_number+' -live_start_index '+e.details.detector_buffer_live_start_index+' -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist "'+e.sdir+'detectorStream.m3u8"' + } + //custom - output + if(e.details.custom_output&&e.details.custom_output!==''){x.pipe+=' '+e.details.custom_output;} + //custom - input flags + if(e.details.cust_input&&e.details.cust_input!==''){x.cust_input+=' '+e.details.cust_input;} + //logging - level + if(e.details.loglevel&&e.details.loglevel!==''){x.loglevel='-loglevel '+e.details.loglevel;}else{x.loglevel='-loglevel error'} + //build record string. + if(e.mode==='record'){ + if(e.details.input_map_choices&&e.details.input_map_choices.record){ + //add input feed map + x.record_string += createFFmpegMap(e.details.input_map_choices.record) + } + //if h264, hls, mp4, or local add the audio codec flag + switch(e.type){ + case'h264':case'hls':case'mp4':case'local': + x.record_string+=x.acodec; + break; + } + //custom flags + if(e.details.cust_record&&e.details.cust_record!==''){x.record_string+=' '+e.details.cust_record;} + //preset flag + if(e.details.preset_record&&e.details.preset_record!==''){x.record_string+=' -preset '+e.details.preset_record;} + //main string write + x.record_string+=x.vcodec+x.record_fps+x.record_video_filters+x.record_dimensions+x.segment; + } + //create executeable FFMPEG command + x.ffmpegCommandString = x.loglevel+x.input_fps; + //progress pipe +// x.ffmpegCommandString += ' -progress pipe:5'; + //add main input + if((e.type==='mp4'||e.type==='mjpeg')&&x.cust_input.indexOf('-re')===-1){ + x.cust_input += ' -re' + } + switch(e.type){ + case'dashcam': + x.ffmpegCommandString += ' -i -'; + break; + case'socket':case'jpeg':case'pipe': + x.ffmpegCommandString += ' -pattern_type glob -f image2pipe'+x.record_fps+' -vcodec mjpeg'+x.cust_input+' -i -'; + break; + case'mjpeg': + x.ffmpegCommandString += ' -reconnect 1 -f mjpeg'+x.cust_input+' -i "'+e.url+'"'; + break; + case'h264':case'hls':case'mp4': + x.ffmpegCommandString += x.cust_input+x.hwaccel+' -i "'+e.url+'"'; + break; + case'local': + x.ffmpegCommandString += x.cust_input+' -i "'+e.path+'"'; + break; + } + //add extra input maps + if(e.details.input_maps){ + e.details.input_maps.forEach(function(v,n){ + x.ffmpegCommandString += createInputMap(n+1,v) + }) + } + //add recording and stream outputs + x.ffmpegCommandString += x.record_string+x.pipe + //hold ffmpeg command for log stream + s.group[e.ke].mon[e.mid].ffmpeg = x.ffmpegCommandString; + //create additional pipes from ffmpeg + x.stdioPipes = []; + var times = config.pipeAddition; + if(e.details.stream_channels){ + times+=e.details.stream_channels.length + } + for(var i=0; i < times; i++){ + x.stdioPipes.push('pipe') + } + x.ffmpegCommandString = s.splitForFFPMEG(x.ffmpegCommandString.replace(/\s+/g,' ').trim()) + return spawn(config.ffmpegDir,x.ffmpegCommandString,{detached: true,stdio:x.stdioPipes}); +} +s.file=function(x,e){ + if(!e){e={}}; + switch(x){ + case'size': + return fs.statSync(e.filename)["size"]; + break; + case'delete': + if(!e){return false;} + return exec('rm -f '+e,{detached: true}); + break; + case'delete_folder': + if(!e){return false;} + return exec('rm -rf '+e,{detached: true}); + break; + case'delete_files': + if(!e.age_type){e.age_type='min'};if(!e.age){e.age='1'}; + exec('find '+e.path+' -type f -c'+e.age_type+' +'+e.age+' -exec rm -f {} +',{detached: true}); + break; + } +} +s.camera=function(x,e,cn,tx){ + if(x!=='motion'){ + var ee=s.init('noReference',e); + if(!e){e={}};if(cn&&cn.ke&&!e.ke){e.ke=cn.ke}; + if(!e.mode){e.mode=x;} + if(!e.id&&e.mid){e.id=e.mid} + } + if(e.details&&(e.details instanceof Object)===false){ + try{e.details=JSON.parse(e.details)}catch(err){} + } + //parse Objects + (['detector_cascades','cords','input_map_choices']).forEach(function(v){ + if(e.details&&e.details[v]&&(e.details[v] instanceof Object)===false){ + try{ + if(e.details[v] === '') e.details[v] = '{}' + e.details[v]=JSON.parse(e.details[v]); + if(!e.details[v])e.details[v]={}; + }catch(err){ + + } + } + }); + //parse Arrays + (['stream_channels','input_maps']).forEach(function(v){ + if(e.details&&e.details[v]&&(e.details[v] instanceof Array)===false){ + try{ + e.details[v]=JSON.parse(e.details[v]); + if(!e.details[v])e.details[v]=[]; + }catch(err){ + e.details[v]=[]; + } + } + }); + s.init(0,{ke:e.ke,mid:e.id}) + switch(x){ + case'buildOptionsFromUrl': + var monitorConfig = cn + URLobject=URL.parse(e) + if(monitorConfig.details.control_url_method === 'ONVIF' && monitorConfig.details.control_base_url === ''){ + URLobject.port = 8000 + }else if(!URLobject.port){ + URLobject.port = 80 + } + options = { + host: URLobject.hostname, + port: URLobject.port, + method: monitorConfig.details.control_url_method, + path: URLobject.pathname, + }; + if(URLobject.query){ + options.path=options.path+'?'+URLobject.query + } + if(URLobject.username&&URLobject.password){ + options.username = URLobject.username + options.password = URLobject.password + options.auth=URLobject.username+':'+URLobject.password + }else if(URLobject.auth){ + var auth = URLobject.auth.split(':') + options.auth=URLobject.auth + options.username = auth[0] + options.password = auth[1] + } + return options + break; + case'control': + if(!s.group[e.ke]||!s.group[e.ke].mon[e.id]){return} + var monitorConfig = s.group[e.ke].mon_conf[e.id]; + if(monitorConfig.details.control!=="1"){s.log(e,{type:lang['Control Error'],msg:lang.ControlErrorText1});return} + if(!monitorConfig.details.control_base_url||monitorConfig.details.control_base_url===''){ + e.base=s.init('url_no_path',monitorConfig); + }else{ + e.base=monitorConfig.details.control_base_url; + } + if(!monitorConfig.details.control_url_stop_timeout || monitorConfig.details.control_url_stop_timeout === ''){ + monitorConfig.details.control_url_stop_timeout = 1000 + } + if(!monitorConfig.details.control_url_method||monitorConfig.details.control_url_method===''){monitorConfig.details.control_url_method="GET"} + var controlURL = e.base+monitorConfig.details['control_url_'+e.direction] + var controlURLOptions = s.camera('buildOptionsFromUrl',controlURL,monitorConfig) + if(monitorConfig.details.control_url_stop_timeout === '0' && monitorConfig.details.control_stop === '1' && s.group[e.ke].mon[e.id].ptzMoving === true){ + e.direction = 'stopMove' + s.group[e.ke].mon[e.id].ptzMoving = false + }else{ + s.group[e.ke].mon[e.id].ptzMoving = true + } + if(monitorConfig.details.control_url_method === 'ONVIF'){ + try{ + var move = function(device){ + var stopOptions = {ProfileToken : device.current_profile.token,'PanTilt': true,'Zoom': true} + switch(e.direction){ + case'center': +// device.services.ptz.gotoHomePosition() + msg = {type:'Center button inactive'} + s.log(e,msg) + cn(msg) + break; + case'stopMove': + msg = {type:'Control Trigger Ended'} + s.log(e,msg) + cn(msg) + device.services.ptz.stop(stopOptions).then((result) => { +// console.log(JSON.stringify(result['data'], null, ' ')); + }).catch((error) => { +// console.error(error); + }); + break; + default: + var controlOptions = { + ProfileToken : device.current_profile.token, + Velocity : {} + } + var onvifDirections = { + "left" : [-1.0,'x'], + "right" : [1.0,'x'], + "down" : [-1.0,'y'], + "up" : [1.0,'y'], + "zoom_in" : [1.0,'zoom'], + "zoom_out" : [-1.0,'zoom'] + } + var direction = onvifDirections[e.direction] + controlOptions.Velocity[direction[1]] = direction[0]; + (['x','y','z']).forEach(function(axis){ + if(!controlOptions.Velocity[axis]) + controlOptions.Velocity[axis] = 0 + }) + if(monitorConfig.details.control_stop=='1'){ + device.services.ptz.continuousMove(controlOptions).then(function(err){ + s.log(e,{type:'Control Trigger Started'}); + if(monitorConfig.details.control_url_stop_timeout !== '0'){ + setTimeout(function(){ + msg = {type:'Control Trigger Ended'} + s.log(e,msg) + cn(msg) + device.services.ptz.stop(stopOptions).then((result) => { +// console.log(JSON.stringify(result['data'], null, ' ')); + }).catch((error) => { + console.log(error); + }); + },monitorConfig.details.control_url_stop_timeout) + } + }).catch(function(err){ + console.log(err) + }); + }else{ + device.services.ptz.absoluteMove(controlOptions).then(function(err){ + msg = {type:'Control Triggered'} + s.log(e,msg); + cn(msg) + }).catch(function(err){ + console.log(err) + }); + } + break; + } + } + //create onvif connection + if(!s.group[e.ke].mon[e.id].onvifConnection){ + s.group[e.ke].mon[e.id].onvifConnection = new onvif.OnvifDevice({ + xaddr : 'http://' + controlURLOptions.host + ':' + controlURLOptions.port + '/onvif/device_service', + user : controlURLOptions.username, + pass : controlURLOptions.password + }) + s.group[e.ke].mon[e.id].onvifConnection.init().then((info) => { + move(s.group[e.ke].mon[e.id].onvifConnection) + }).catch(function(error){ + console.log(error) + s.log(e,{type:lang['Control Error'],msg:error}) + }) + }else{ + move(s.group[e.ke].mon[e.id].onvifConnection) + } + }catch(err){ + console.log(err) + msg = {type:lang['Control Error'],msg:{msg:lang.ControlErrorText2,error:err,options:controlURLOptions,direction:e.direction}} + s.log(e,msg) + cn(msg) + } + }else{ + var stopCamera = function(){ + var stopURL = e.base+monitorConfig.details['control_url_'+e.direction+'_stop'] + var options = s.camera('buildOptionsFromUrl',stopURL,monitorConfig) + var requestOptions = { + url : stopURL, + method : options.method, + auth : { + user : options.username, + pass : options.password + } + } + if(monitorConfig.details.control_digest_auth === '1'){ + requestOptions.sendImmediately = true + } + request(requestOptions,function(err,data){ + if(err){ + msg = {ok:false,type:'Control Error',msg:err} + }else{ + msg = {ok:true,type:'Control Trigger Ended'} + } + cn(msg) + s.log(e,msg); + }) + } + if(e.direction === 'stopMove'){ + stopCamera() + }else{ + var requestOptions = { + url : controlURL, + method : controlURLOptions.method, + auth : { + user : controlURLOptions.username, + pass : controlURLOptions.password + } + } + if(monitorConfig.details.control_digest_auth === '1'){ + requestOptions.sendImmediately = true + } + request(requestOptions,function(err,data){ + if(err){ + msg = {ok:false,type:'Control Error',msg:err}; + cn(msg) + s.log(e,msg); + return + } + if(monitorConfig.details.control_stop=='1'&&e.direction!=='center'){ + s.log(e,{type:'Control Triggered Started'}); + if(monitorConfig.details.control_url_stop_timeout > 0){ + setTimeout(function(){ + stopCamera() + },monitorConfig.details.control_url_stop_timeout) + } + }else{ + msg = {ok:true,type:'Control Triggered'}; + cn(msg) + s.log(e,msg); + } + }) + } + } + break; + case'snapshot'://get snapshot from monitor URL + if(config.doSnapshot===true){ + if(e.mon.mode!=='stop'){ + if(e.mon.details.snap==='1'){ + fs.readFile(s.dir.streams+e.ke+'/'+e.mid+'/s.jpg',function(err,data){ + if(err){s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke);return}; + s.tx({f:'monitor_snapshot',snapshot:data,snapshot_format:'ab',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + }) + }else{ + e.url=s.init('url',e.mon); + switch(e.mon.type){ + case'mjpeg':case'h264':case'local': + if(e.mon.type==='local'){e.url=e.mon.path;} + e.spawn=spawn(config.ffmpegDir,('-loglevel quiet -i '+e.url+' -s 400x400 -r 25 -ss 1.8 -frames:v 1 -f singlejpeg pipe:1').split(' '),{detached: true}) + e.spawn.stdout.on('data',function(data){ + e.snapshot_sent=true; s.tx({f:'monitor_snapshot',snapshot:data.toString('base64'),snapshot_format:'b64',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + e.spawn.kill(); + }); + e.spawn.on('close',function(data){ + if(!e.snapshot_sent){ + s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + } + delete(e.snapshot_sent); + }); + break; + case'jpeg': + request({url:e.url,method:'GET',encoding:null},function(err,data){ + if(err){s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke);return}; + s.tx({f:'monitor_snapshot',snapshot:data.body,snapshot_format:'ab',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + }) + break; + default: + s.tx({f:'monitor_snapshot',snapshot:'...',snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + break; + } + } + }else{ + s.tx({f:'monitor_snapshot',snapshot:'Disabled',snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + } + }else{ + s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke) + } + break; + case'record_off'://stop recording and start + if(!s.group[e.ke].mon[e.id].record){s.group[e.ke].mon[e.id].record={}} + s.group[e.ke].mon[e.id].record.yes=0; + s.camera('start',e); + break; + case'watch_on'://live streamers - join +// if(s.group[e.ke].mon[e.id].watch[cn.id]){s.camera('watch_off',e,cn,tx);return} + if(!cn.monitor_watching){cn.monitor_watching={}} + if(!cn.monitor_watching[e.id]){cn.monitor_watching[e.id]={ke:e.ke}} + s.group[e.ke].mon[e.id].watch[cn.id]={}; +// if(Object.keys(s.group[e.ke].mon[e.id].watch).length>0){ +// s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND mid=?',[e.ke,e.id],function(err,r) { +// if(r&&r[0]){ +// r=r[0]; +// r.url=s.init('url',r); +// s.group[e.ke].mon.type=r.type; +// } +// }) +// } + break; + case'watch_off'://live streamers - leave + if(cn.monitor_watching){delete(cn.monitor_watching[e.id])} + if(s.group[e.ke].mon[e.id]&&s.group[e.ke].mon[e.id].watch){ + delete(s.group[e.ke].mon[e.id].watch[cn.id]),e.ob=Object.keys(s.group[e.ke].mon[e.id].watch).length + if(e.ob===0){ + delete(s.group[e.ke].mon[e.id].watch) + } + }else{ + e.ob=0; + } + if(tx){tx({f:'monitor_watch_off',ke:e.ke,id:e.id,cnid:cn.id})}; + s.tx({viewers:e.ob,ke:e.ke,id:e.id},'MON_'+e.id); + break; + case'restart'://restart monitor + s.camera('stop',e) + setTimeout(function(){ + s.camera(e.mode,e) + },1300) + break; + case'idle':case'stop'://stop monitor + if(!s.group[e.ke]||!s.group[e.ke].mon[e.id]){return} + if(config.childNodes.enabled === true && config.childNodes.mode === 'master' && s.group[e.ke].mon[e.id].childNode && s.childNodes[s.group[e.ke].mon[e.id].childNode].activeCameras[e.ke+e.id]){ + s.group[e.ke].mon[e.id].started = 0 + s.cx({ + //function + f : 'cameraStop', + //data, options + d : s.group[e.ke].mon_conf[e.id] + },s.group[e.ke].mon[e.id].childNodeId) + s.cx({f:'sync',sync:s.group[e.ke].mon_conf[e.id],ke:e.ke,mid:e.id},s.group[e.ke].mon[e.id].childNodeId); + }else{ + if(s.group[e.ke].mon[e.id].eventBasedRecording.process){ + clearTimeout(s.group[e.ke].mon[e.id].eventBasedRecording.timeout) + s.group[e.ke].mon[e.id].eventBasedRecording.allowEnd=true; + s.group[e.ke].mon[e.id].eventBasedRecording.process.kill('SIGTERM'); + } + if(s.group[e.ke].mon[e.id].fswatch){s.group[e.ke].mon[e.id].fswatch.close();delete(s.group[e.ke].mon[e.id].fswatch)} + if(s.group[e.ke].mon[e.id].fswatchStream){s.group[e.ke].mon[e.id].fswatchStream.close();delete(s.group[e.ke].mon[e.id].fswatchStream)} + if(s.group[e.ke].mon[e.id].last_frame){delete(s.group[e.ke].mon[e.id].last_frame)} + if(s.group[e.ke].mon[e.id].started!==1){return} + s.kill(s.group[e.ke].mon[e.id].spawn,e); + if(e.neglectTriggerTimer===1){ + delete(e.neglectTriggerTimer); + }else{ + clearTimeout(s.group[e.ke].mon[e.id].trigger_timer) + delete(s.group[e.ke].mon[e.id].trigger_timer) + } + clearInterval(s.group[e.ke].mon[e.id].running); + clearInterval(s.group[e.ke].mon[e.id].detector_notrigger_timeout) + clearTimeout(s.group[e.ke].mon[e.id].err_fatal_timeout); + s.group[e.ke].mon[e.id].started=0; + if(s.group[e.ke].mon[e.id].record){s.group[e.ke].mon[e.id].record.yes=0} + s.tx({f:'monitor_stopping',mid:e.id,ke:e.ke,time:s.formattedTime()},'GRP_'+e.ke); + s.camera('snapshot',{mid:e.id,ke:e.ke,mon:e}) + if(x==='stop'){ + s.log(e,{type:lang['Monitor Stopped'],msg:lang.MonitorStoppedText}); + clearTimeout(s.group[e.ke].mon[e.id].delete) + if(e.delete===1){ + s.group[e.ke].mon[e.id].delete=setTimeout(function(){ + delete(s.group[e.ke].mon[e.id]); + delete(s.group[e.ke].mon_conf[e.id]); + },1000*60); + } + }else{ + s.tx({f:'monitor_idle',mid:e.id,ke:e.ke,time:s.formattedTime()},'GRP_'+e.ke); + s.log(e,{type:lang['Monitor Idling'],msg:lang.MonitorIdlingText}); + } + } + break; + case'start':case'record'://watch or record monitor url + s.init(0,{ke:e.ke,mid:e.id}) + if(!s.group[e.ke].mon_conf[e.id]){s.group[e.ke].mon_conf[e.id]=s.init('noReference',e);} + e.url = s.init('url',e); + if(s.group[e.ke].mon[e.id].started===1){ + //stop action, monitor already started or recording + return + } + //lock this function + s.group[e.ke].mon[e.id].started = 1; + //create host string without username and password + e.hosty = e.host.split('@'); + if(e.hosty[1]){ + //username and password found + e.hosty = e.hosty[1] + }else{ + //no username or password in `host` string + e.hosty = e.hosty[0] + } + //set recording status + if(x==='record'){ + s.group[e.ke].mon[e.id].record.yes=1; + }else{ + s.group[e.ke].mon[e.mid].record.yes=0; + } + //set the recording directory + if(e.details && e.details.dir && e.details.dir !== '' && config.childNodes.mode !== 'child'){ + //addStorage choice + e.dir=s.checkCorrectPathEnding(e.details.dir)+e.ke+'/'; + if (!fs.existsSync(e.dir)){ + fs.mkdirSync(e.dir); + } + e.dir=e.dir+e.id+'/'; + if (!fs.existsSync(e.dir)){ + fs.mkdirSync(e.dir); + } + }else{ + //MAIN videos dir + e.dir=s.dir.videos+e.ke+'/'; + if (!fs.existsSync(e.dir)){ + fs.mkdirSync(e.dir); + } + e.dir=s.dir.videos+e.ke+'/'+e.id+'/'; + if (!fs.existsSync(e.dir)){ + fs.mkdirSync(e.dir); + } + } + //set the temporary files directory + var setStreamDir = function(){ + //stream dir + e.sdir=s.dir.streams+e.ke+'/'; + if (!fs.existsSync(e.sdir)){ + fs.mkdirSync(e.sdir); + } + e.sdir=s.dir.streams+e.ke+'/'+e.id+'/'; + if (!fs.existsSync(e.sdir)){ + fs.mkdirSync(e.sdir); + }else{ + s.file('delete_folder',e.sdir+'*') + } + } + setStreamDir() + //set up fatal error handler + if(e.details.fatal_max===''){ + e.details.fatal_max = 10 + }else{ + e.details.fatal_max = parseFloat(e.details.fatal_max) + } + var errorFatal = function(errorMessage){ + if(config.debugSystem === true){ + console.log(errorMessage,(new Error()).stack) + } + clearTimeout(s.group[e.ke].mon[e.id].err_fatal_timeout); + ++errorFatalCount; + if(s.group[e.ke].mon[e.id].started===1){ + s.group[e.ke].mon[e.id].err_fatal_timeout=setTimeout(function(){ + if(e.details.fatal_max!==0&&errorFatalCount>e.details.fatal_max){ + s.camera('stop',{id:e.id,ke:e.ke}) + }else{ + launchMonitorProcesses() + }; + },5000); + }else{ + s.kill(s.group[e.ke].mon[e.id].spawn,e); + } + } + errorFatalCount = 0; + //set master based process launcher + launchMonitorProcesses = function(){ + if(e.details.detector_trigger=='1'){ + s.group[e.ke].mon[e.id].motion_lock=setTimeout(function(){ + clearTimeout(s.group[e.ke].mon[e.id].motion_lock); + delete(s.group[e.ke].mon[e.id].motion_lock); + },30000) + } + //cutoff time and recording check interval + if(!e.details.cutoff||e.details.cutoff===''){e.cutoff=15}else{e.cutoff=parseFloat(e.details.cutoff)}; + if(isNaN(e.cutoff)===true){e.cutoff=15} + //start "no motion" checker + if(e.details.detector=='1'&&e.details.detector_notrigger=='1'){ + if(!e.details.detector_notrigger_timeout||e.details.detector_notrigger_timeout===''){ + e.details.detector_notrigger_timeout=10 + } + e.detector_notrigger_timeout=parseFloat(e.details.detector_notrigger_timeout)*1000*60; + s.sqlQuery('SELECT mail FROM Users WHERE ke=? AND details NOT LIKE ?',[e.ke,'%"sub"%'],function(err,r){ + r=r[0]; + s.group[e.ke].mon[e.id].detector_notrigger_timeout_function=function(){ + if(config.mail&&e.details.detector_notrigger_mail=='1'){ + e.mailOptions = { + from: '"ShinobiCCTV" ', // sender address + to: r.mail, // list of receivers + subject: lang.NoMotionEmailText1+' '+e.name+' ('+e.id+')', // Subject line + html: ''+lang.NoMotionEmailText2+' '+e.details.detector_notrigger_timeout+' '+lang.minutes+'.', + }; + e.mailOptions.html+='
'+lang['Monitor Name']+' : '+e.name+'
' + e.mailOptions.html+='
'+lang['Monitor ID']+' : '+e.id+'
' + nodemailer.sendMail(e.mailOptions, (error, info) => { + if (error) { + s.systemLog('detector:notrigger:sendMail',error) + s.tx({f:'error',ff:'detector_notrigger_mail',id:e.id,ke:e.ke,error:error},'GRP_'+e.ke); + return ; + } + s.tx({f:'detector_notrigger_mail',id:e.id,ke:e.ke,info:info},'GRP_'+e.ke); + }); + } + } + clearInterval(s.group[e.ke].mon[e.id].detector_notrigger_timeout) + s.group[e.ke].mon[e.id].detector_notrigger_timeout=setInterval(s.group[e.ke].mon[e.id].detector_notrigger_timeout_function,s.group[e.ke].mon[e.id].detector_notrigger_timeout) + }) + } + var resetStreamCheck=function(){ + clearTimeout(s.group[e.ke].mon[e.id].checkStream) + s.group[e.ke].mon[e.id].checkStream=setTimeout(function(){ + if(s.group[e.ke].mon[e.id].started===1){ + launchMonitorProcesses(); + s.log(e,{type:lang['Camera is not streaming'],msg:{msg:lang['Restarting Process']}}); + } + },60000*1); + } + if(config.childNodes.mode !== 'child' && s.platform!=='darwin' && (x==='record' || (x==='start'&&e.details.detector_record_method==='sip'))){ + //check if ffmpeg is recording + s.group[e.ke].mon[e.id].fswatch = fs.watch(e.dir, {encoding : 'utf8'}, (event, filename) => { + switch(event){ + case'rename': + s.group[e.ke].mon[e.id].open = filename.split('.')[0] + break; + case'change': + clearTimeout(s.group[e.ke].mon[e.id].checker) + clearTimeout(s.group[e.ke].mon[e.id].checkStream) + s.group[e.ke].mon[e.id].checker=setTimeout(function(){ + if(s.group[e.ke].mon[e.id].started===1){ + launchMonitorProcesses(); + s.log(e,{type:lang['Camera is not recording'],msg:{msg:lang['Restarting Process']}}); + } + },60000 * e.cutoff * 1.1); + break; + } + }); + } + if( + //is MacOS + s.platform !== 'darwin' && + //is Watch-Only or Record + (x === 'start' || x === 'record') && + //if JPEG API enabled or Stream Type is HLS + (e.details.stream_type === 'jpeg' || e.details.stream_type === 'hls' || e.details.snap === '1') + ){ + s.group[e.ke].mon[e.id].fswatchStream = fs.watch(e.sdir, {encoding : 'utf8'}, () => { + resetStreamCheck() + }) + } + s.camera('snapshot',{mid:e.id,ke:e.ke,mon:e}) + //check host to see if has password and user in it + setStreamDir() + clearTimeout(s.group[e.ke].mon[e.id].checker) + if(s.group[e.ke].mon[e.id].started===1){ + e.error_count=0; + s.group[e.ke].mon[e.id].error_socket_timeout_count=0; + s.kill(s.group[e.ke].mon[e.id].spawn,e); + startVideoProcessor=function(err,o){ + if(o.success===true){ + e.frames=0; + if(!s.group[e.ke].mon[e.id].record){s.group[e.ke].mon[e.id].record={yes:1}}; + //launch ffmpeg (main) + s.group[e.ke].mon[e.id].spawn = s.ffmpeg(e); + //on unexpected exit restart + s.group[e.ke].mon[e.id].spawn_exit=function(){ + if(s.group[e.ke].mon[e.id].started===1){ + if(e.details.loglevel!=='quiet'){ + s.log(e,{type:lang['Process Unexpected Exit'],msg:{msg:lang['Process Crashed for Monitor']+' : '+e.id,cmd:s.group[e.ke].mon[e.id].ffmpeg}}); + } + errorFatal('Process Unexpected Exit'); + } + } + s.group[e.ke].mon[e.id].spawn.on('end',s.group[e.ke].mon[e.id].spawn_exit) + s.group[e.ke].mon[e.id].spawn.on('exit',s.group[e.ke].mon[e.id].spawn_exit) + // +// s.group[e.ke].mon[e.id].spawn.stdio[5].on('data',function(data){ +// data = data.toString(); +// console.log('---') +// var json = {} +// data.split('\n').forEach(function(v){ +// var vv = v.split('=') +// json[vv[0]] = vv[1] +// }) +// console.log(json) +// }) + //emitter for mjpeg + if(!e.details.stream_mjpeg_clients||e.details.stream_mjpeg_clients===''||isNaN(e.details.stream_mjpeg_clients)===false){e.details.stream_mjpeg_clients=20;}else{e.details.stream_mjpeg_clients=parseInt(e.details.stream_mjpeg_clients)} + s.group[e.ke].mon[e.id].emitter = new events.EventEmitter().setMaxListeners(e.details.stream_mjpeg_clients); + s.log(e,{type:'FFMPEG Process Started',msg:{cmd:s.group[e.ke].mon[e.id].ffmpeg}}); + s.tx({f:'monitor_starting',mode:x,mid:e.id,time:s.formattedTime()},'GRP_'+e.ke); + //start workers + if(e.type==='jpeg'){ + if(!e.details.sfps||e.details.sfps===''){ + var capture_fps=parseFloat(e.details.sfps); + if(isNaN(capture_fps)){capture_fps=1} + } + if(s.group[e.ke].mon[e.id].spawn){ + s.group[e.ke].mon[e.id].spawn.stdin.on('error',function(err){ + if(err&&e.details.loglevel!=='quiet'){ + s.log(e,{type:'STDIN ERROR',msg:err}); + } + }) + }else{ + if(x==='record'){ + s.log(e,{type:lang.FFmpegCantStart,msg:lang.FFmpegCantStartText}); + return + } + } + e.captureOne=function(f){ + s.group[e.ke].mon[e.id].record.request=request({url:e.url,method:'GET',encoding: null,timeout:15000},function(err,data){ + if(err){ + return; + } + }).on('data',function(d){ + if(!e.buffer0){ + e.buffer0=[d] + }else{ + e.buffer0.push(d); + } + if((d[d.length-2] === 0xFF && d[d.length-1] === 0xD9)){ + e.buffer0=Buffer.concat(e.buffer0); + ++e.frames; + if(s.group[e.ke].mon[e.id].spawn&&s.group[e.ke].mon[e.id].spawn.stdin){ + s.group[e.ke].mon[e.id].spawn.stdin.write(e.buffer0); + } + if(s.group[e.ke].mon[e.id].started===1){ + s.group[e.ke].mon[e.id].record.capturing=setTimeout(function(){ + e.captureOne() + },1000/capture_fps); + } + e.buffer0=null; + } + if(!e.timeOut){ + e.timeOut=setTimeout(function(){e.error_count=0;delete(e.timeOut);},3000); + } + + }).on('error', function(err){ + ++e.error_count; + clearTimeout(e.timeOut);delete(e.timeOut); + if(e.details.loglevel!=='quiet'){ + s.log(e,{type:lang['JPEG Error'],msg:{msg:lang.JPEGErrorText,info:err}}); + switch(err.code){ + case'ESOCKETTIMEDOUT': + case'ETIMEDOUT': + ++s.group[e.ke].mon[e.id].error_socket_timeout_count + if(e.details.fatal_max!==0&&s.group[e.ke].mon[e.id].error_socket_timeout_count>e.details.fatal_max){ + s.log(e,{type:lang['Fatal Maximum Reached'],msg:{code:'ESOCKETTIMEDOUT',msg:lang.FatalMaximumReachedText}}); + s.camera('stop',e) + }else{ + s.log(e,{type:lang['Restarting Process'],msg:{code:'ESOCKETTIMEDOUT',msg:lang.FatalMaximumReachedText}}); + s.camera('restart',e) + } + return; + break; + } + } + if(e.details.fatal_max!==0&&e.error_count>e.details.fatal_max){ + clearTimeout(s.group[e.ke].mon[e.id].record.capturing); + launchMonitorProcesses(); + } + }); + } + e.captureOne() + } + if(!s.group[e.ke]||!s.group[e.ke].mon[e.id]){s.init(0,e)} + s.group[e.ke].mon[e.id].spawn.on('error',function(er){ + s.log(e,{type:'Spawn Error',msg:er});errorFatal('Spawn Error') + }); + if(e.details.detector==='1'){ + s.ocvTx({f:'init_monitor',id:e.id,ke:e.ke}) + //frames from motion detect + if(e.details.detector_pam==='1'){ + var width, + height, + globalSensitivity, + fullFrame = false + if(s.group[e.ke].mon_conf[e.id].details.detector_scale_x===''||s.group[e.ke].mon_conf[e.id].details.detector_scale_y===''){ + width = s.group[e.ke].mon_conf[e.id].details.detector_scale_x; + height = s.group[e.ke].mon_conf[e.id].details.detector_scale_y; + }else{ + width = e.width + height = e.height + } + if(e.details.detector_sensitivity===''){ + globalSensitivity = 10 + }else{ + globalSensitivity = parseInt(e.details.detector_sensitivity) + } + if(e.details.detector_frame==='1'){ + fullFrame={ + name:'FULL_FRAME', + sensitivity:globalSensitivity, + points:[ + [0,0], + [0,height], + [width,height], + [width,0] + ] + }; + } + var regions = s.createPamDiffRegionArray(s.group[e.ke].mon_conf[e.id].details.cords,globalSensitivity,fullFrame); + if(!s.group[e.ke].mon[e.id].noiseFilterArray)s.group[e.ke].mon[e.id].noiseFilterArray = {} + var noiseFilterArray = s.group[e.ke].mon[e.id].noiseFilterArray + Object.keys(regions.notForPam).forEach(function(name){ + if(!noiseFilterArray[name])noiseFilterArray[name]=[]; + }) + s.group[e.ke].mon[e.id].pamDiff = new PamDiff({grayscale: 'luminosity', regions : regions.forPam}); + s.group[e.ke].mon[e.id].p2p = new P2P(); + var sendTrigger = function(trigger){ + var detectorObject = { + f:'trigger', + id:e.id, + ke:e.ke, + name:trigger.name, + details:{ + plug:'built-in', + name:trigger.name, + reason:'motion', + confidence:trigger.percent, + }, + plates:[], + imgHeight:height, + imgWidth:width + } + detectorObject.doObjectDetection = (s.ocv && e.details.detector_use_detect_object === '1') + s.camera('motion',detectorObject) + if(detectorObject.doObjectDetection === true){ + s.ocvTx({f:'frame',mon:s.group[e.ke].mon_conf[e.id].details,ke:e.ke,id:e.id,time:s.formattedTime(),frame:s.group[e.ke].mon[e.id].lastJpegDetectorFrame}); + } + } + var filterTheNoise = function(trigger){ + if(noiseFilterArray[trigger.name].length > 2){ + var thePreviousTriggerPercent = noiseFilterArray[trigger.name][noiseFilterArray[trigger.name].length - 1]; + var triggerDifference = trigger.percent - thePreviousTriggerPercent; + var noiseRange = e.details.detector_noise_filter_range + if(!noiseRange || noiseRange === ''){ + noiseRange = 6 + } + noiseRange = parseFloat(noiseRange) + if(((trigger.percent - thePreviousTriggerPercent) < noiseRange)||(thePreviousTriggerPercent - trigger.percent) > -noiseRange){ + noiseFilterArray[trigger.name].push(trigger.percent); + } + }else{ + noiseFilterArray[trigger.name].push(trigger.percent); + } + if(noiseFilterArray[trigger.name].length > 10){ + noiseFilterArray[trigger.name] = noiseFilterArray[trigger.name].splice(1,10) + } + var theNoise = 0; + noiseFilterArray[trigger.name].forEach(function(v,n){ + theNoise += v; + }) + theNoise = theNoise / noiseFilterArray[trigger.name].length; +// console.log(noiseFilterArray[trigger.name]) +// console.log(theNoise) + var triggerPercentWithoutNoise = trigger.percent - theNoise; + if(triggerPercentWithoutNoise > regions.notForPam[trigger.name].sensitivity){ + sendTrigger(trigger); + } + } + if(e.details.detector_noise_filter==='1'){ + s.group[e.ke].mon[e.id].pamDiff.on('diff', (data) => { + data.trigger.forEach(filterTheNoise) + }) + }else{ + s.group[e.ke].mon[e.id].pamDiff.on('diff', (data) => { + data.trigger.forEach(sendTrigger) + }) + } + + s.group[e.ke].mon[e.id].spawn.stdio[3].pipe(s.group[e.ke].mon[e.id].p2p).pipe(s.group[e.ke].mon[e.id].pamDiff) + if(e.details.detector_use_detect_object === '1'){ + s.group[e.ke].mon[e.id].spawn.stdio[4].on('data',function(d){ + s.group[e.ke].mon[e.id].lastJpegDetectorFrame = d + }) + } + }else{ + s.group[e.ke].mon[e.id].spawn.stdio[3].on('data',function(d){ + s.ocvTx({f:'frame',mon:s.group[e.ke].mon_conf[e.id].details,ke:e.ke,id:e.id,time:s.formattedTime(),frame:d}); + }) + } + } + //frames to stream + switch(e.details.stream_type){ + case'mp4': + s.group[e.ke].mon[e.id].mp4frag['MAIN'] = new Mp4Frag(); + s.group[e.ke].mon[e.id].spawn.stdio[1].pipe(s.group[e.ke].mon[e.id].mp4frag['MAIN']) + break; + case'flv': + e.frame_to_stream=function(d){ + if(!s.group[e.ke].mon[e.id].firstStreamChunk['MAIN'])s.group[e.ke].mon[e.id].firstStreamChunk['MAIN'] = d; + e.frame_to_stream=function(d){ + resetStreamCheck() + s.group[e.ke].mon[e.id].emitter.emit('data',d); + } + e.frame_to_stream(d) + } + break; + case'mjpeg': + e.frame_to_stream=function(d){ + resetStreamCheck() + s.group[e.ke].mon[e.id].emitter.emit('data',d); + } + break; +// case'pam': +// s.group[e.ke].mon[e.id].p2pStream = new P2P(); +// s.group[e.ke].mon[e.id].spawn.stdout.pipe(s.group[e.ke].mon[e.id].p2pStream) +// s.group[e.ke].mon[e.id].p2pStream.on('pam',function(d){ +// resetStreamCheck() +// s.tx({f:'pam_frame',ke:e.ke,id:e.id,imageData:{ +// data : d.pixels, +// height : d.height, +// width : d.width +// }},'MON_STREAM_'+e.id); +// }) +// break; + case'b64':case undefined:case null:case'': + var buffer + e.frame_to_stream=function(d){ + resetStreamCheck() + if(!buffer){ + buffer=[d] + }else{ + buffer.push(d); + } + if((d[d.length-2] === 0xFF && d[d.length-1] === 0xD9)){ + s.group[e.ke].mon[e.id].emitter.emit('data',Buffer.concat(buffer)); + buffer=null; + } + } + break; + } + if(e.frame_to_stream){ + s.group[e.ke].mon[e.id].spawn.stdout.on('data',e.frame_to_stream); + } + if(e.details.stream_channels&&e.details.stream_channels!==''){ + var createStreamEmitter = function(channel,number){ + var pipeNumber = number+config.pipeAddition; + if(!s.group[e.ke].mon[e.id].emitterChannel[pipeNumber]){ + s.group[e.ke].mon[e.id].emitterChannel[pipeNumber] = new events.EventEmitter().setMaxListeners(0); + } + var frame_to_stream + switch(channel.stream_type){ + case'mp4': + s.group[e.ke].mon[e.id].mp4frag[pipeNumber] = new Mp4Frag(); + s.group[e.ke].mon[e.id].spawn.stdio[pipeNumber].pipe(s.group[e.ke].mon[e.id].mp4frag[pipeNumber]) + break; + case'mjpeg': + frame_to_stream=function(d){ + s.group[e.ke].mon[e.id].emitterChannel[pipeNumber].emit('data',d); + } + break; + case'flv': + frame_to_stream=function(d){ + if(!s.group[e.ke].mon[e.id].firstStreamChunk[pipeNumber])s.group[e.ke].mon[e.id].firstStreamChunk[pipeNumber] = d; + frame_to_stream=function(d){ + s.group[e.ke].mon[e.id].emitterChannel[pipeNumber].emit('data',d); + } + frame_to_stream(d) + } + break; + case'h264': + frame_to_stream=function(d){ + s.group[e.ke].mon[e.id].emitterChannel[pipeNumber].emit('data',d); + } + break; + } + if(frame_to_stream){ + s.group[e.ke].mon[e.id].spawn.stdio[pipeNumber].on('data',frame_to_stream); + } + } + e.details.stream_channels.forEach(createStreamEmitter) + } + if(x==='record'||e.type==='mjpeg'||e.type==='h264'||e.type==='local'){ + s.group[e.ke].mon[e.id].spawn.stderr.on('data',function(d){ + d=d.toString(); + e.chk=function(x){return d.indexOf(x)>-1;} + switch(true){ + //mp4 output with webm encoder chosen + case e.chk('Could not find tag for vp8'): + case e.chk('Only VP8 or VP9 Video'): + case e.chk('Could not write header'): +// switch(e.ext){ +// case'mp4': +// e.details.vcodec='libx264' +// e.details.acodec='none' +// break; +// case'webm': +// e.details.vcodec='libvpx' +// e.details.acodec='none' +// break; +// } +// if(e.details.stream_type==='hls'){ +// e.details.stream_vcodec='libx264' +// e.details.stream_acodec='no' +// } +// s.camera('restart',e) + return s.log(e,{type:lang['Incorrect Settings Chosen'],msg:{msg:d}}) + break; + case e.chk('NULL @'): + case e.chk('RTP: missed'): + case e.chk('deprecated pixel format used, make sure you did set range correctly'): + return + break; +// case e.chk('av_interleaved_write_frame'): + case e.chk('Connection refused'): + case e.chk('Connection timed out'): + //restart + setTimeout(function(){ + s.log(e,{type:lang['Connection timed out'],msg:lang['Retrying...']}); + errorFatal('Connection timed out'); + },1000) + break; +// case e.chk('No such file or directory'): +// case e.chk('Unable to open RTSP for listening'): +// case e.chk('timed out'): +// case e.chk('Invalid data found when processing input'): +// case e.chk('Immediate exit requested'): +// case e.chk('reset by peer'): +// if(e.frames===0&&x==='record'){s.video('delete',e)}; +// setTimeout(function(){ +// if(!s.group[e.ke].mon[e.id].spawn){launchMonitorProcesses()} +// },2000) +// break; + case e.chk('mjpeg_decode_dc'): + case e.chk('bad vlc'): + case e.chk('error dc'): + launchMonitorProcesses() + break; + case /T[0-9][0-9]-[0-9][0-9]-[0-9][0-9]./.test(d): + var filename = d.split('.')[0]+'.'+e.ext + s.video('insertCompleted',e,{ + file : filename + }) + s.log(e,{type:lang['Video Finished'],msg:{filename:d}}) + if( + e.details.detector==='1'&& + s.group[e.ke].mon[e.id].started===1&& + e.details&& + e.details.detector_record_method==='del'&& + e.details.detector_delete_motionless_videos==='1'&& + s.group[e.ke].mon[e.id].detector_motion_count===0 + ){ + if(e.details.loglevel!=='quiet'){ + s.log(e,{type:lang['Delete Motionless Video'],msg:filename}); + } + s.video('delete',{ + filename : filename, + ke : e.ke, + id : e.id + }) + } + s.group[e.ke].mon[e.id].detector_motion_count = 0 + return; + break; + } + s.log(e,{type:"FFMPEG STDERR",msg:d}) + }); + } + }else{ + s.log(e,{type:lang["Ping Failed"],msg:lang.skipPingText1}); + errorFatal("Ping Failed");return; + } + } + if(e.type!=='socket'&&e.type!=='dashcam'&&e.protocol!=='udp'&&e.type!=='local'||e.details.skip_ping === '1'){ + connectionTester.test(e.hosty,e.port,2000,startVideoProcessor); + }else{ + startVideoProcessor(null,{success:true}) + } + }else{ + s.kill(s.group[e.ke].mon[e.id].spawn,e); + } + } + //start drawing files + delete(s.group[e.ke].mon[e.id].childNode) + if(config.childNodes.enabled === true && config.childNodes.mode === 'master'){ + var childNodeList = Object.keys(s.childNodes) + if(childNodeList.length>0){ + e.ch_stop = 0; + launchMonitorProcesses = function(){ + startVideoProcessor = function(){ + s.cx({ + //function + f : 'cameraStart', + //mode + mode : x, + //data, options + d : s.group[e.ke].mon_conf[e.id] + },s.group[e.ke].mon[e.id].childNodeId) + } + if(e.type!=='socket'&&e.type!=='dashcam'&&e.protocol!=='udp'&&e.type!=='local' && e.details.skip_ping !== '1'){ + console.log(e.hosty,e.port) + connectionTester.test(e.hosty,e.port,2000,function(err,o){ + if(o.success===true){ + startVideoProcessor() + }else{ + s.log(e,{type:lang["Ping Failed"],msg:lang.skipPingText1}); + errorFatal("Ping Failed");return; + } + }) + }else{ + startVideoProcessor() + } + } + childNodeList.forEach(function(ip){ + if(e.ch_stop===0&&s.childNodes[ip].cpu<80){ + e.ch_stop=1; + s.childNodes[ip].activeCameras[e.ke+e.id] = s.init('noReference',s.group[e.ke].mon_conf[e.id]); + s.group[e.ke].mon[e.id].childNode = ip; + s.group[e.ke].mon[e.id].childNodeId = s.childNodes[ip].cnid; + s.cx({f:'sync',sync:s.group[e.ke].mon_conf[e.id],ke:e.ke,mid:e.id},s.group[e.ke].mon[e.id].childNodeId); + launchMonitorProcesses(); + } + }) + }else{ + launchMonitorProcesses(); + } + }else{ + launchMonitorProcesses(); + } + break; + case'motion': + var d=e; + if(s.group[d.ke].mon[d.id].open){ + d.details.videoTime = s.group[d.ke].mon[d.id].open; + } + var detailString = JSON.stringify(d.details); + if(!s.group[d.ke]||!s.group[d.ke].mon[d.id]){ + return s.systemLog(lang['No Monitor Found, Ignoring Request']) + } + d.mon=s.group[d.ke].mon_conf[d.id]; + if(!s.group[d.ke].mon[d.id].detector_motion_count){ + s.group[d.ke].mon[d.id].detector_motion_count=0 + } + s.group[d.ke].mon[d.id].detector_motion_count+=1 + if(s.group[d.ke].mon[d.id].motion_lock){ + return + } + var detector_lock_timeout + if(!d.mon.details.detector_lock_timeout||d.mon.details.detector_lock_timeout===''){ + detector_lock_timeout = 2000 + } + detector_lock_timeout = parseFloat(d.mon.details.detector_lock_timeout); + if(!s.group[d.ke].mon[d.id].detector_lock_timeout){ + s.group[d.ke].mon[d.id].detector_lock_timeout=setTimeout(function(){ + clearTimeout(s.group[d.ke].mon[d.id].detector_lock_timeout) + delete(s.group[d.ke].mon[d.id].detector_lock_timeout) + },detector_lock_timeout) + }else{ + return + } + if(d.doObjectDetection !== true){ + //save this detection result in SQL, only coords. not image. + if(d.mon.details.detector_save==='1'){ + s.sqlQuery('INSERT INTO Events (ke,mid,details) VALUES (?,?,?)',[d.ke,d.id,detailString]) + } + if(d.mon.details.detector_notrigger=='1'){ + var detector_notrigger_timeout + if(!d.mon.details.detector_notrigger_timeout||d.mon.details.detector_notrigger_timeout===''){ + detector_notrigger_timeout = 10 + } + detector_notrigger_timeout = parseFloat(d.mon.details.detector_notrigger_timeout)*1000*60; + s.group[e.ke].mon[e.id].detector_notrigger_timeout = detector_notrigger_timeout; + clearInterval(s.group[d.ke].mon[d.id].detector_notrigger_timeout) + s.group[d.ke].mon[d.id].detector_notrigger_timeout = setInterval(s.group[d.ke].mon[d.id].detector_notrigger_timeout_function,detector_notrigger_timeout) + } + if(d.mon.details.detector_webhook=='1'){ + var detector_webhook_url = d.mon.details.detector_webhook_url + .replace(/{{TIME}}/g,s.timeObject(new Date).format()) + .replace(/{{MONITOR_ID}}/g,d.id) + .replace(/{{GROUP_KEY}}/g,d.ke) + .replace(/{{DETAILS}}/g,detailString) + http.get(detector_webhook_url, function(data) { + data.setEncoding('utf8'); + var chunks=''; + data.on('data', (chunk) => { + chunks+=chunk; + }); + data.on('end', () => { + + }); + + }).on('error', function(e) { + + }).end(); + } + var detector_timeout + if(!d.mon.details.detector_timeout||d.mon.details.detector_timeout===''){ + detector_timeout = 10 + }else{ + detector_timeout = parseFloat(d.mon.details.detector_timeout) + } + if(d.mon.mode=='start'&&d.mon.details.detector_trigger==='1'&&d.mon.details.detector_record_method==='sip'){ + //s.group[d.ke].mon[d.id].eventBasedRecording.timeout + // clearTimeout(s.group[d.ke].mon[d.id].eventBasedRecording.timeout) + s.group[d.ke].mon[d.id].eventBasedRecording.timeout = setTimeout(function(){ + s.group[d.ke].mon[d.id].eventBasedRecording.allowEnd=true; + },detector_timeout * 950 * 60) + if(!s.group[d.ke].mon[d.id].eventBasedRecording.process){ + if(!d.auth){ + d.auth=s.gid(); + } + if(!s.group[d.ke].users[d.auth]){ + s.group[d.ke].users[d.auth]={system:1,details:{},lang:lang} + } + s.group[d.ke].mon[d.id].eventBasedRecording.allowEnd = false; + var runRecord = function(){ + var filename = s.formattedTime()+'.mp4' + s.log(d,{type:"Traditional Recording",msg:"Started"}) + //-t 00:'+s.timeObject(new Date(detector_timeout * 1000 * 60)).format('mm:ss')+' + s.group[d.ke].mon[d.id].eventBasedRecording.process = spawn(config.ffmpegDir,s.splitForFFPMEG(('-loglevel warning -analyzeduration 1000000 -probesize 1000000 -re -i http://'+config.ip+':'+config.port+'/'+d.auth+'/hls/'+d.ke+'/'+d.id+'/detectorStream.m3u8 -t 00:'+s.timeObject(new Date(detector_timeout * 1000 * 60)).format('mm:ss')+' -c:v copy -strftime 1 "'+s.video('getDir',d.mon) + filename + '"').replace(/\s+/g,' ').trim())) + var ffmpegError=''; + var error + s.group[d.ke].mon[d.id].eventBasedRecording.process.stderr.on('data',function(data){ + s.log(d,{type:"Traditional Recording",msg:data.toString()}) + }) + s.group[d.ke].mon[d.id].eventBasedRecording.process.on('close',function(){ + if(!s.group[d.ke].mon[d.id].eventBasedRecording.allowEnd){ + s.log(d,{type:"Traditional Recording",msg:"Detector Recording Process Exited Prematurely. Restarting."}) + runRecord() + return + } + s.video('insertCompleted',d.mon,{ + file : filename + }) + s.log(d,{type:"Traditional Recording",msg:"Detector Recording Complete"}) + delete(s.group[d.ke].users[d.auth]) + s.log(d,{type:"Traditional Recording",msg:'Clear Recorder Process'}) + delete(s.group[d.ke].mon[d.id].eventBasedRecording.process) + delete(s.group[d.ke].mon[d.id].eventBasedRecording.timeout) + clearTimeout(s.group[d.ke].mon[d.id].checker) + }) + } + runRecord() + } + }else if(d.mon.mode!=='stop'&&d.mon.details.detector_trigger=='1'&&d.mon.details.detector_record_method==='hot'){ + if(!d.auth){ + d.auth=s.gid(); + } + if(!s.group[d.ke].users[d.auth]){ + s.group[d.ke].users[d.auth]={system:1,details:{},lang:lang} + } + d.urlQuery=[] + d.url='http://'+config.ip+':'+config.port+'/'+d.auth+'/monitor/'+d.ke+'/'+d.id+'/record/'+detector_timeout+'/min'; + if(d.mon.details.watchdog_reset!=='0'){ + d.urlQuery.push('reset=1') + } + if(d.mon.details.detector_trigger_record_fps&&d.mon.details.detector_trigger_record_fps!==''&&d.mon.details.detector_trigger_record_fps!=='0'){ + d.urlQuery.push('fps='+d.mon.details.detector_trigger_record_fps) + } + if(d.urlQuery.length>0){ + d.url+='?'+d.urlQuery.join('&') + } + http.get(d.url, function(data) { + data.setEncoding('utf8'); + var chunks=''; + data.on('data', (chunk) => { + chunks+=chunk; + }); + data.on('end', () => { + delete(s.group[d.ke].users[d.auth]) + d.cx.f='detector_record_engaged'; + d.cx.msg=JSON.parse(chunks); + s.tx(d.cx,'GRP_'+d.ke); + }); + + }).on('error', function(e) { + + }).end(); + } + //mailer + if(config.mail&&!s.group[d.ke].mon[d.id].detector_mail&&d.mon.details.detector_mail==='1'){ + s.sqlQuery('SELECT mail FROM Users WHERE ke=? AND details NOT LIKE ?',[d.ke,'%"sub"%'],function(err,r){ + r=r[0]; + var detector_mail_timeout + if(!d.mon.details.detector_mail_timeout||d.mon.details.detector_mail_timeout===''){ + detector_mail_timeout = 1000*60*10; + }else{ + detector_mail_timeout = parseFloat(d.mon.details.detector_mail_timeout)*1000*60; + } + //lock mailer so you don't get emailed on EVERY trigger event. + s.group[d.ke].mon[d.id].detector_mail=setTimeout(function(){ + //unlock so you can mail again. + clearTimeout(s.group[d.ke].mon[d.id].detector_mail); + delete(s.group[d.ke].mon[d.id].detector_mail); + },detector_mail_timeout); + d.frame_filename='Motion_'+(d.mon.name.replace(/[^\w\s]/gi, ''))+'_'+d.id+'_'+d.ke+'_'+s.formattedTime()+'.jpg'; + fs.readFile(s.dir.streams+'/'+d.ke+'/'+d.id+'/s.jpg',function(err, frame){ + d.mailOptions = { + from: '"ShinobiCCTV" ', // sender address + to: r.mail, // list of receivers + subject: lang.Event+' - '+d.frame_filename, // Subject line + html: ''+lang.EventText1+' '+s.timeObject(new Date).format()+'.', + }; + if(err){ + s.systemLog(lang.EventText2+' '+d.ke+' '+d.id,err) + }else{ + d.mailOptions.attachments=[ + { + filename: d.frame_filename, + content: frame + } + ] + d.mailOptions.html=''+lang.EventText3+'' + } + Object.keys(d.details).forEach(function(v,n){ + d.mailOptions.html+='
'+v+' : '+d.details[v]+'
' + }) + nodemailer.sendMail(d.mailOptions, (error, info) => { + if (error) { + s.systemLog(lang.MailError,error) + return ; + } + }); + }) + }); + } + if(d.mon.details.detector_command_enable==='1'&&!s.group[d.ke].mon[d.id].detector_command){ + var detector_command_timeout + if(!d.mon.details.detector_command_timeout||d.mon.details.detector_command_timeout===''){ + detector_command_timeout = 1000*60*10; + }else{ + detector_command_timeout = parseFloat(d.mon.details.detector_command_timeout)*1000*60; + } + s.group[d.ke].mon[d.id].detector_command=setTimeout(function(){ + clearTimeout(s.group[d.ke].mon[d.id].detector_command); + delete(s.group[d.ke].mon[d.id].detector_command); + + },detector_command_timeout); + var detector_command = d.mon.details.detector_command + .replace(/{{TIME}}/g,s.timeObject(new Date).format()) + .replace(/{{MONITOR_ID}}/g,d.id) + .replace(/{{GROUP_KEY}}/g,d.ke) + .replace(/{{DETAILS}}/g,detailString) + if(d.details.confidence){ + detector_command = detector_command + .replace(/{{CONFIDENCE}}/g,d.details.confidence) + } + exec(detector_command,{detached: true}) + } + } + //show client machines the event + d.cx={f:'detector_trigger',id:d.id,ke:d.ke,details:d.details,doObjectDetection:d.doObjectDetection}; + s.tx(d.cx,'DETECTOR_'+d.ke+d.id); + break; + } + if(typeof cn==='function'){setTimeout(function(){cn()},1000);} +} + +//function for receiving detector data +s.pluginEventController=function(d){ + switch(d.f){ + case'trigger': + s.camera('motion',d) + break; + case's.tx': + s.tx(d.data,d.to) + break; + case'sql': + sql.query(d.query,d.values); + break; + case'log': + s.systemLog('PLUGIN : '+d.plug+' : ',d) + break; + } +} +//multi plugin connections +s.connectedPlugins={} +s.pluginInitiatorSuccess=function(mode,d,cn){ + s.systemLog('pluginInitiatorSuccess',d) + if(mode==='client'){ + //is in client mode (camera.js is client) + cn.pluginEngine=d.plug + if(!s.connectedPlugins[d.plug]){ + s.connectedPlugins[d.plug]={plug:d.plug} + } + s.systemLog('Connected to plugin : Detector - '+d.plug+' - '+d.type) + switch(d.type){ + default:case'detector': + s.ocv={started:s.timeObject(),id:cn.id,plug:d.plug,notice:d.notice,isClientPlugin:true}; + cn.ocv=1; + s.tx({f:'detector_plugged',plug:d.plug,notice:d.notice},'CPU') + break; + } + }else{ + //is in host mode (camera.js is client) + switch(d.type){ + default:case'detector': + s.ocv={started:s.timeObject(),id:"host",plug:d.plug,notice:d.notice,isHostPlugin:true}; + break; + } + } + s.connectedPlugins[d.plug].plugged=true + s.tx({f:'readPlugins',ke:d.ke},'CPU') + s.ocvTx({f:'api_key',key:d.plug}) + s.api[d.plug]={pluginEngine:d.plug,permissions:{},details:{},ip:'0.0.0.0'}; +} +s.pluginInitiatorFail=function(mode,d,cn){ + s.connectedPlugins[d.plug].plugged=false + if(mode==='client'){ + //is in client mode (camera.js is client) + cn.disconnect() + }else{ + //is in host mode (camera.js is client) + } +} +if(config.plugins&&config.plugins.length>0){ + config.plugins.forEach(function(v){ + s.connectedPlugins[v.id]={plug:v.id} + if(v.enabled===false){return} + if(v.mode==='host'){ + //is in host mode (camera.js is client) + if(v.https===true){ + v.https='https://' + }else{ + v.https='http://' + } + if(!v.port){ + v.port=80 + } + var socket = socketIOclient(v.https+v.host+':'+v.port) + s.connectedPlugins[v.id].tx = function(x){return socket.emit('f',x)} + socket.on('connect', function(cn){ + s.systemLog('Connected to plugin (host) : '+v.id) + s.connectedPlugins[v.id].tx({f:'init_plugin_as_host',key:v.key}) + }); + socket.on('init',function(d){ + s.systemLog('Initialize Plugin : Host',d) + if(d.ok===true){ + s.pluginInitiatorSuccess("host",d) + }else{ + s.pluginInitiatorFail("host",d) + } + }); + socket.on('ocv',s.pluginEventController); + socket.on('disconnect', function(){ + s.connectedPlugins[v.id].plugged=false + delete(s.api[v.id]) + s.systemLog('Plugin Disconnected : '+v.id) + s.connectedPlugins[v.id].reconnector = setInterval(function(){ + if(socket.connected===true){ + clearInterval(s.connectedPlugins[v.id].reconnector) + }else{ + socket.connect() + } + },1000*2) + }); + s.connectedPlugins[v.id].ws = socket; + } + }) +} +////socket controller +s.cn=function(cn){return{id:cn.id,ke:cn.ke,uid:cn.uid}} +io.on('connection', function (cn) { +var tx; + //set "client" detector plugin event function + cn.on('ocv',function(d){ + if(!cn.pluginEngine&&d.f==='init'){ + if(config.pluginKeys[d.plug]===d.pluginKey){ + s.pluginInitiatorSuccess("client",d,cn) + }else{ + s.pluginInitiatorFail("client",d,cn) + } + }else{ + if(config.pluginKeys[d.plug]===d.pluginKey){ + s.pluginEventController(d) + }else{ + cn.disconnect() + } + } + }) + //unique Base64 socket stream + cn.on('Base64',function(d){ + if(!s.group[d.ke]||!s.group[d.ke].mon||!s.group[d.ke].mon[d.id]){ + cn.disconnect();return; + } + cn.ip=cn.request.connection.remoteAddress; + var toUTC = function(){ + return new Date().toISOString(); + } + var tx=function(z){cn.emit('data',z);} + d.failed=function(msg){ + tx({f:'stop_reconnect',msg:msg,token_used:d.auth,ke:d.ke}); + cn.disconnect(); + } + d.success=function(r){ + r=r[0]; + var Emitter,chunkChannel + if(!d.channel){ + Emitter = s.group[d.ke].mon[d.id].emitter + chunkChannel = 'MAIN' + }else{ + Emitter = s.group[d.ke].mon[d.id].emitterChannel[parseInt(d.channel)+config.pipeAddition] + chunkChannel = parseInt(d.channel)+config.pipeAddition + } + if(!Emitter){ + cn.disconnect();return; + } + if(!d.channel)d.channel = 'MAIN'; + cn.ke=d.ke, + cn.uid=d.uid, + cn.auth=d.auth; + cn.channel=d.channel; + cn.removeListenerOnDisconnect=true; + cn.socketVideoStream=d.id; + var contentWriter + cn.closeSocketVideoStream = function(){ + Emitter.removeListener('data', contentWriter); + } + Emitter.on('data',contentWriter = function(base64){ + tx(base64) + }) + } + //check if auth key is user's temporary session key + if(s.group[d.ke]&&s.group[d.ke].users&&s.group[d.ke].users[d.auth]){ + d.success(s.group[d.ke].users[d.auth]); + }else{ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND auth=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + s.sqlQuery('SELECT * FROM API WHERE ke=? AND code=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details) + if(r.details.auth_socket==='1'){ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND uid=?',[r.ke,r.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + d.failed('User not found') + } + }) + }else{ + d.failed('Permissions for this key do not allow authentication with Websocket') + } + }else{ + d.failed('Not an API key') + } + }) + } + }) + } + }) + //unique FLV socket stream + cn.on('FLV',function(d){ + if(!s.group[d.ke]||!s.group[d.ke].mon||!s.group[d.ke].mon[d.id]){ + cn.disconnect();return; + } + cn.ip=cn.request.connection.remoteAddress; + var toUTC = function(){ + return new Date().toISOString(); + } + var tx=function(z){cn.emit('data',z);} + d.failed=function(msg){ + tx({f:'stop_reconnect',msg:msg,token_used:d.auth,ke:d.ke}); + cn.disconnect(); + } + d.success=function(r){ + r=r[0]; + var Emitter,chunkChannel + if(!d.channel){ + Emitter = s.group[d.ke].mon[d.id].emitter + chunkChannel = 'MAIN' + }else{ + Emitter = s.group[d.ke].mon[d.id].emitterChannel[parseInt(d.channel)+config.pipeAddition] + chunkChannel = parseInt(d.channel)+config.pipeAddition + } + if(!Emitter){ + cn.disconnect();return; + } + if(!d.channel)d.channel = 'MAIN'; + cn.ke=d.ke, + cn.uid=d.uid, + cn.auth=d.auth; + cn.channel=d.channel; + cn.removeListenerOnDisconnect=true; + cn.socketVideoStream=d.id; + var contentWriter + cn.closeSocketVideoStream = function(){ + Emitter.removeListener('data', contentWriter); + } + tx({time:toUTC(),buffer:s.group[d.ke].mon[d.id].firstStreamChunk[chunkChannel]}) + Emitter.on('data',contentWriter = function(buffer){ + tx({time:toUTC(),buffer:buffer}) + }) + } + if(s.group[d.ke]&&s.group[d.ke].users&&s.group[d.ke].users[d.auth]){ + d.success(s.group[d.ke].users[d.auth]); + }else{ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND auth=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + s.sqlQuery('SELECT * FROM API WHERE ke=? AND code=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details) + if(r.details.auth_socket==='1'){ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND uid=?',[r.ke,r.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + d.failed('User not found') + } + }) + }else{ + d.failed('Permissions for this key do not allow authentication with Websocket') + } + }else{ + d.failed('Not an API key') + } + }) + } + }) + } + }) + //unique MP4 socket stream + cn.on('MP4',function(d){ + if(!s.group[d.ke]||!s.group[d.ke].mon||!s.group[d.ke].mon[d.id]){ + cn.disconnect();return; + } + cn.ip=cn.request.connection.remoteAddress; + var toUTC = function(){ + return new Date().toISOString(); + } + var tx=function(z){cn.emit('data',z);} + d.failed=function(msg){ + tx({f:'stop_reconnect',msg:msg,token_used:d.auth,ke:d.ke}); + cn.disconnect(); + } + d.success=function(r){ + r=r[0]; + var Emitter,chunkChannel + if(!d.channel){ + Emitter = s.group[d.ke].mon[d.id].emitter + chunkChannel = 'MAIN' + }else{ + Emitter = s.group[d.ke].mon[d.id].emitterChannel[parseInt(d.channel)+config.pipeAddition] + chunkChannel = parseInt(d.channel)+config.pipeAddition + } + if(!Emitter){ + cn.disconnect();return; + } + if(!d.channel)d.channel = 'MAIN'; + cn.ke=d.ke, + cn.uid=d.uid, + cn.auth=d.auth; + cn.channel=d.channel; + cn.socketVideoStream=d.id; + var mp4frag = s.group[d.ke].mon[d.id].mp4frag[d.channel]; + var onInitialized = () => { + cn.emit('mime', mp4frag.mime); + mp4frag.removeListener('initialized', onInitialized); + }; + //event listener + var onSegment = function(data){ + cn.emit('segment', data); + }; + cn.closeSocketVideoStream = function(){ + mp4frag.removeListener('segment', onSegment) + mp4frag.removeListener('initialized', onInitialized) + } + cn.on('MP4Command',function(msg){ + switch (msg) { + case 'mime' ://client is requesting mime + var mime = mp4frag.mime; + if (mime) { + cn.emit('mime', mime); + } else { + mp4frag.on('initialized', onInitialized); + } + break; + case 'initialization' ://client is requesting initialization segment + cn.emit('initialization', mp4frag.initialization); + break; + case 'segment' ://client is requesting a SINGLE segment + var segment = mp4frag.segment; + if (segment) { + cn.emit('segment', segment); + } else { + mp4frag.once('segment', onSegment); + } + break; + case 'segments' ://client is requesting ALL segments + //send current segment first to start video asap + var segment = mp4frag.segment; + if (segment) { + cn.emit('segment', segment); + } + //add listener for segments being dispatched by mp4frag + mp4frag.on('segment', onSegment); + break; + case 'pause' : + mp4frag.removeListener('segment', onSegment); + break; + case 'resume' : + mp4frag.on('segment', onSegment); + break; + case 'stop' ://client requesting to stop receiving segments + cn.closeSocketVideoStream() + break; + } + }) + } + if(s.group[d.ke]&&s.group[d.ke].users&&s.group[d.ke].users[d.auth]){ + d.success(s.group[d.ke].users[d.auth]); + }else{ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND auth=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + s.sqlQuery('SELECT * FROM API WHERE ke=? AND code=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details) + if(r.details.auth_socket==='1'){ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND uid=?',[r.ke,r.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + d.failed('User not found') + } + }) + }else{ + d.failed('Permissions for this key do not allow authentication with Websocket') + } + }else{ + d.failed('Not an API key') + } + }) + } + }) + } + }) + //main socket control functions + cn.on('f',function(d){ + if(!cn.ke&&d.f==='init'){//socket login + cn.ip=cn.request.connection.remoteAddress; + tx=function(z){if(!z.ke){z.ke=cn.ke;};cn.emit('f',z);} + d.failed=function(){tx({ok:false,msg:'Not Authorized',token_used:d.auth,ke:d.ke});cn.disconnect();} + d.success=function(r){ + r=r[0];cn.join('GRP_'+d.ke);cn.join('CPU'); + cn.ke=d.ke, + cn.uid=d.uid, + cn.auth=d.auth; + if(!s.group[d.ke])s.group[d.ke]={}; +// if(!s.group[d.ke].vid)s.group[d.ke].vid={}; + if(!s.group[d.ke].users)s.group[d.ke].users={}; +// s.group[d.ke].vid[cn.id]={uid:d.uid}; + s.group[d.ke].users[d.auth]={cnid:cn.id,uid:r.uid,mail:r.mail,details:JSON.parse(r.details),logged_in_at:s.timeObject(new Date).format(),login_type:'Dashboard'} + try{s.group[d.ke].users[d.auth].details=JSON.parse(r.details)}catch(er){} + if(s.group[d.ke].users[d.auth].details.get_server_log!=='0'){ + cn.join('GRPLOG_'+d.ke) + } + s.group[d.ke].users[d.auth].lang=s.getLanguageFile(s.group[d.ke].users[d.auth].details.lang) + s.log({ke:d.ke,mid:'$USER'},{type:s.group[d.ke].users[d.auth].lang['Websocket Connected'],msg:{mail:r.mail,id:d.uid,ip:cn.ip}}) + if(!s.group[d.ke].mon){ + s.group[d.ke].mon={} + if(!s.group[d.ke].mon){s.group[d.ke].mon={}} + } + if(s.ocv){ + tx({f:'detector_plugged',plug:s.ocv.plug,notice:s.ocv.notice}) + s.ocvTx({f:'readPlugins',ke:d.ke}) + } + tx({f:'users_online',users:s.group[d.ke].users}) + s.tx({f:'user_status_change',ke:d.ke,uid:cn.uid,status:1,user:s.group[d.ke].users[d.auth]},'GRP_'+d.ke) + s.init('diskUsedEmit',d) + s.init('apps',d) + s.sqlQuery('SELECT * FROM API WHERE ke=? AND uid=?',[d.ke,d.uid],function(err,rrr) { + tx({ + f:'init_success', + users:s.group[d.ke].vid, + apis:rrr, + os:{ + platform:s.platform, + cpuCount:os.cpus().length, + totalmem:s.totalmem + } + }) + try{ + s.sqlQuery('SELECT * FROM Monitors WHERE ke=?', [d.ke], function(err,r) { + if(r && r[0]){ + r.forEach(function(monitor){ + s.camera('snapshot',{mid:monitor.mid,ke:monitor.ke,mon:monitor}) + }) + } + }) + }catch(err){ + console.log(err) + } + }) + } + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND auth=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + s.sqlQuery('SELECT * FROM API WHERE ke=? AND code=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details) + if(r.details.auth_socket==='1'){ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND uid=?',[r.ke,r.uid],function(err,r) { + if(r&&r[0]){ + d.success(r) + }else{ + d.failed() + } + }) + }else{ + d.failed() + } + }else{ + d.failed() + } + }) + } + }) + return; + } + if((d.id||d.uid||d.mid)&&cn.ke){ + try{ + switch(d.f){ + case'ocv_in': + s.ocvTx(d.data) + break; + case'monitorOrder': + if(d.monitorOrder&&d.monitorOrder instanceof Object){ + s.sqlQuery('SELECT details FROM Users WHERE uid=? AND ke=?',[cn.uid,cn.ke],function(err,r){ + if(r&&r[0]){ + r=JSON.parse(r[0].details); + r.monitorOrder=d.monitorOrder; + s.sqlQuery('UPDATE Users SET details=? WHERE uid=? AND ke=?',[JSON.stringify(r),cn.uid,cn.ke]) + } + }) + } + break; + case'update': + if(!config.updateKey){ + tx({error:lang.updateKeyText1}); + return; + } + if(d.key===config.updateKey){ + exec('chmod +x '+__dirname+'/UPDATE.sh&&'+__dirname+'/UPDATE.sh',{detached: true}) + }else{ + tx({error:lang.updateKeyText2}); + } + break; + case'cron': + if(s.group[cn.ke]&&s.group[cn.ke].users[cn.auth].details&&!s.group[cn.ke].users[cn.auth].details.sub){ + s.tx({f:d.ff},s.cron.id) + } + break; + case'api': + switch(d.ff){ + case'delete': + d.set=[],d.ar=[]; + d.form.ke=cn.ke;d.form.uid=cn.uid;delete(d.form.ip); + if(!d.form.code){tx({f:'form_incomplete',form:'APIs'});return} + d.for=Object.keys(d.form); + d.for.forEach(function(v){ + d.set.push(v+'=?'),d.ar.push(d.form[v]); + }); + s.sqlQuery('DELETE FROM API WHERE '+d.set.join(' AND '),d.ar,function(err,r){ + if(!err){ + tx({f:'api_key_deleted',form:d.form}); + delete(s.api[d.form.code]); + }else{ + s.systemLog('API Delete Error : '+e.ke+' : '+' : '+e.mid,err) + } + }) + break; + case'add': + d.set=[],d.qu=[],d.ar=[]; + d.form.ke=cn.ke,d.form.uid=cn.uid,d.form.code=s.gid(30); + d.for=Object.keys(d.form); + d.for.forEach(function(v){ + d.set.push(v),d.qu.push('?'),d.ar.push(d.form[v]); + }); + s.sqlQuery('INSERT INTO API ('+d.set.join(',')+') VALUES ('+d.qu.join(',')+')',d.ar,function(err,r){ + d.form.time=s.formattedTime(new Date,'YYYY-DD-MM HH:mm:ss'); + if(!err){tx({f:'api_key_added',form:d.form});}else{s.systemLog(err)} + }); + break; + } + break; + case'settings': + switch(d.ff){ + case'filters': + switch(d.fff){ + case'save':case'delete': + s.sqlQuery('SELECT details FROM Users WHERE ke=? AND uid=?',[d.ke,d.uid],function(err,r){ + if(r&&r[0]){ + r=r[0]; + d.d=JSON.parse(r.details); + if(d.form.id===''){d.form.id=s.gid(5)} + if(!d.d.filters)d.d.filters={}; + //save/modify or delete + if(d.fff==='save'){ + d.d.filters[d.form.id]=d.form; + }else{ + delete(d.d.filters[d.form.id]); + } + s.sqlQuery('UPDATE Users SET details=? WHERE ke=? AND uid=?',[JSON.stringify(d.d),d.ke,d.uid],function(err,r){ + tx({f:'filters_change',uid:d.uid,ke:d.ke,filters:d.d.filters}); + }); + } + }) + break; + } + break; + case'edit': + s.sqlQuery('SELECT details FROM Users WHERE ke=? AND uid=?',[d.ke,d.uid],function(err,r){ + if(r&&r[0]){ + r=r[0]; + d.d=JSON.parse(r.details); + if(d.d.get_server_log==='1'){ + cn.join('GRPLOG_'+d.ke) + }else{ + cn.leave('GRPLOG_'+d.ke) + } + ///unchangeable from client side, so reset them in case they did. + d.form.details=JSON.parse(d.form.details) + //admin permissions + d.form.details.permissions=d.d.permissions + d.form.details.edit_size=d.d.edit_size + d.form.details.edit_days=d.d.edit_days + d.form.details.use_admin=d.d.use_admin + d.form.details.use_webdav=d.d.use_webdav + d.form.details.use_ldap=d.d.use_ldap + //check + if(d.d.edit_days=="0"){ + d.form.details.days=d.d.days; + } + if(d.d.edit_size=="0"){ + d.form.details.size=d.d.size; + } + if(d.d.sub){ + d.form.details.sub=d.d.sub; + if(d.d.monitors){d.form.details.monitors=d.d.monitors;} + if(d.d.allmonitors){d.form.details.allmonitors=d.d.allmonitors;} + if(d.d.video_delete){d.form.details.video_delete=d.d.video_delete;} + if(d.d.video_view){d.form.details.video_view=d.d.video_view;} + if(d.d.monitor_edit){d.form.details.monitor_edit=d.d.monitor_edit;} + if(d.d.size){d.form.details.size=d.d.size;} + if(d.d.days){d.form.details.days=d.d.days;} + delete(d.form.details.mon_groups) + } + var newSize = d.form.details.size + d.form.details=JSON.stringify(d.form.details) + /// + d.set=[],d.ar=[]; + if(d.form.pass&&d.form.pass!==''){d.form.pass=s.md5(d.form.pass);}else{delete(d.form.pass)}; + delete(d.form.password_again); + d.for=Object.keys(d.form); + d.for.forEach(function(v){ + d.set.push(v+'=?'),d.ar.push(d.form[v]); + }); + d.ar.push(d.ke),d.ar.push(d.uid); + s.sqlQuery('UPDATE Users SET '+d.set.join(',')+' WHERE ke=? AND uid=?',d.ar,function(err,r){ + if(!d.d.sub){ + s.group[d.ke].sizeLimit = parseFloat(newSize) + delete(s.group[d.ke].webdav) + s.init('apps',d) + } + tx({f:'user_settings_change',uid:d.uid,ke:d.ke,form:d.form}); + }); + } + }) + break; + } + break; + case'monitor': + switch(d.ff){ + case'get': + switch(d.fff){ + case'videos&events': + if(!d.eventLimit){ + d.eventLimit=500 + }else{ + d.eventLimit = parseInt(d.eventLimit); + } + if(!d.eventStartDate&&d.startDate){ + d.eventStartDate=d.startDate + } + if(!d.eventEndDate&&d.endDate){ + d.eventEndDate=d.endDate + } + var monitorQuery = '' + var monitorValues = [] + var permissions = s.group[d.ke].users[cn.auth].details; + if(!d.mid){ + if(permissions.sub&&permissions.monitors&&permissions.allmonitors!=='1'){ + try{permissions.monitors=JSON.parse(permissions.monitors);}catch(er){} + var or = []; + permissions.monitors.forEach(function(v,n){ + or.push('mid=?'); + monitorValues.push(v) + }) + monitorQuery += ' AND ('+or.join(' OR ')+')' + } + }else if(!permissions.sub||permissions.allmonitors!=='0'||permissions.monitors.indexOf(d.mid)>-1){ + monitorQuery += ' and mid=?'; + monitorValues.push(d.mid) + } + var getEvents = function(callback){ + var eventQuery = 'SELECT * FROM Events WHERE ke=?'; + var eventQueryValues = [cn.ke]; + if(d.eventStartDate&&d.eventStartDate!==''){ + d.eventStartDate=d.eventStartDate.replace('T',' ') + if(d.eventEndDate&&d.eventEndDate!==''){ + d.eventEndDate=d.eventEndDate.replace('T',' ') + eventQuery+=' AND `time` >= ? AND `time` <= ?'; + eventQueryValues.push(decodeURIComponent(d.eventStartDate)) + eventQueryValues.push(decodeURIComponent(d.eventEndDate)) + }else{ + eventQuery+=' AND `time` >= ?'; + eventQueryValues.push(decodeURIComponent(d.eventStartDate)) + } + } + if(monitorValues.length>0){ + eventQuery += monitorQuery; + eventQueryValues = eventQueryValues.concat(monitorValues); + } + eventQuery+=' ORDER BY `time` DESC LIMIT '+d.eventLimit+''; + s.sqlQuery(eventQuery,eventQueryValues,function(err,r){ + if(err){ + console.log(eventQuery) + console.error('LINE 2428',err) + setTimeout(function(){ + getEvents(callback) + },2000) + }else{ + if(!r){r=[]} + r.forEach(function(v,n){ + r[n].details=JSON.parse(v.details); + }) + callback(r) + } + }) + } + if(!d.videoLimit&&d.limit){ + d.videoLimit=d.limit + eventQuery.push() + } + if(!d.videoStartDate&&d.startDate){ + d.videoStartDate=d.startDate + } + if(!d.videoEndDate&&d.endDate){ + d.videoEndDate=d.endDate + } + var getVideos = function(callback){ + var videoQuery='SELECT * FROM Videos WHERE ke=?'; + var videoQueryValues=[cn.ke]; + if(d.videoStartDate||d.videoEndDate){ + if(!d.videoStartDateOperator||d.videoStartDateOperator==''){ + d.videoStartDateOperator='>=' + } + if(!d.videoEndDateOperator||d.videoEndDateOperator==''){ + d.videoEndDateOperator='<=' + } + switch(true){ + case(d.videoStartDate&&d.videoStartDate!==''&&d.videoEndDate&&d.videoEndDate!==''): + d.videoStartDate=d.videoStartDate.replace('T',' ') + d.videoEndDate=d.videoEndDate.replace('T',' ') + videoQuery+=' AND `time` '+d.videoStartDateOperator+' ? AND `end` '+d.videoEndDateOperator+' ?'; + videoQueryValues.push(d.videoStartDate) + videoQueryValues.push(d.videoEndDate) + break; + case(d.videoStartDate&&d.videoStartDate!==''): + d.videoStartDate=d.videoStartDate.replace('T',' ') + videoQuery+=' AND `time` '+d.videoStartDateOperator+' ?'; + videoQueryValues.push(d.videoStartDate) + break; + case(d.videoEndDate&&d.videoEndDate!==''): + d.videoEndDate=d.videoEndDate.replace('T',' ') + videoQuery+=' AND `end` '+d.videoEndDateOperator+' ?'; + videoQueryValues.push(d.videoEndDate) + break; + } + } + if(monitorValues.length>0){ + videoQuery += monitorQuery; + videoQueryValues = videoQueryValues.concat(monitorValues); + } + videoQuery+=' ORDER BY `time` DESC'; + if(!d.videoLimit||d.videoLimit==''){ + d.videoLimit='100' + } + if(d.videoLimit!=='0'){ + videoQuery+=' LIMIT '+d.videoLimit + } + s.sqlQuery(videoQuery,videoQueryValues,function(err,r){ + if(err){ + console.log(videoQuery) + console.error('LINE 2416',err) + setTimeout(function(){ + getVideos(callback) + },2000) + }else{ + s.video('linkBuild',r,cn.auth) + callback({total:r.length,limit:d.videoLimit,videos:r}) + } + }) + } + getVideos(function(videos){ + getEvents(function(events){ + tx({ + f:'drawPowerVideoMainTimeLine', + videos:videos, + events:events + }) + }) + }) + break; + } + break; + case'control': + s.camera('control',d,function(resp){ + tx({f:'control',response:resp}) + }) + break; + case'jpeg_off': + delete(cn.jpeg_on); + if(cn.monitor_watching){ + Object.keys(cn.monitor_watching).forEach(function(n,v){ + v=cn.monitor_watching[n]; + cn.join('MON_STREAM_'+n); + }); + } + tx({f:'mode_jpeg_off'}) + break; + case'jpeg_on': + cn.jpeg_on=true; + if(cn.monitor_watching){ + Object.keys(cn.monitor_watching).forEach(function(n,v){ + v=cn.monitor_watching[n]; + cn.leave('MON_STREAM_'+n); + }); + } + tx({f:'mode_jpeg_on'}) + break; + case'watch_on': + if(!d.ke){d.ke=cn.ke} + s.init(0,{mid:d.id,ke:d.ke}); + if(!s.group[d.ke]||!s.group[d.ke].mon[d.id]||s.group[d.ke].mon[d.id].started===0){return false} + s.camera(d.ff,d,cn,tx) + cn.join('MON_'+d.id); + cn.join('DETECTOR_'+d.ke+d.id); + if(cn.jpeg_on!==true){ + cn.join('MON_STREAM_'+d.id); + } if(s.group[d.ke]&&s.group[d.ke].mon&&s.group[d.ke].mon[d.id]&&s.group[d.ke].mon[d.id].watch){ + + tx({f:'monitor_watch_on',id:d.id,ke:d.ke}) + s.tx({viewers:Object.keys(s.group[d.ke].mon[d.id].watch).length,ke:d.ke,id:d.id},'MON_'+d.id) + } + break; + case'watch_off': + if(!d.ke){d.ke=cn.ke;};cn.leave('MON_'+d.id);s.camera(d.ff,d,cn,tx); + s.tx({viewers:d.ob,ke:d.ke,id:d.id},'MON_'+d.id) + break; + case'start':case'stop': + s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND mid=?',[cn.ke,d.id],function(err,r) { + if(r&&r[0]){r=r[0] + s.camera(d.ff,{type:r.type,url:s.init('url',r),id:d.id,mode:d.ff,ke:cn.ke}); + } + }) + break; + } + break; +// case'video': +// switch(d.ff){ +// case'fix': +// s.video('fix',d) +// break; +// } +// break; + case'ffprobe': + if(s.group[cn.ke].users[cn.auth]){ + switch(d.ff){ + case'stop': + exec('kill -9 '+s.group[cn.ke].users[cn.auth].ffprobe.pid,{detatched: true}) + break; + default: + if(s.group[cn.ke].users[cn.auth].ffprobe){ + return + } + s.group[cn.ke].users[cn.auth].ffprobe=1; + tx({f:'ffprobe_start'}) + exec('ffprobe '+('-v quiet -print_format json -show_format -show_streams '+d.query),function(err,data){ + tx({f:'ffprobe_data',data:data.toString('utf8')}) + delete(s.group[cn.ke].users[cn.auth].ffprobe) + tx({f:'ffprobe_stop'}) + }) + //auto kill in 30 seconds + setTimeout(function(){ + exec('kill -9 '+d.pid,{detached: true}) + },30000) + break; + } + } + break; + case'onvif': + d.ip=d.ip.replace(/ /g,''); + d.port=d.port.replace(/ /g,''); + if(d.ip===''){ + var interfaces = os.networkInterfaces(); + var addresses = []; + for (var k in interfaces) { + for (var k2 in interfaces[k]) { + var address = interfaces[k][k2]; + if (address.family === 'IPv4' && !address.internal) { + addresses.push(address.address); + } + } + } + d.arr=[] + addresses.forEach(function(v){ + if(v.indexOf('0.0.0')>-1){return false} + v=v.split('.'); + delete(v[3]); + v=v.join('.'); + d.arr.push(v+'1-'+v+'254') + }) + d.ip=d.arr.join(',') + } + if(d.port===''){ + d.port='80,8080,8000,7575,8081,554' + } + d.ip.split(',').forEach(function(v){ + if(v.indexOf('-')>-1){ + v=v.split('-'); + d.IP_RANGE_START = v[0], + d.IP_RANGE_END = v[1]; + }else{ + d.IP_RANGE_START = v; + d.IP_RANGE_END = v; + } + if(!d.IP_LIST){ + d.IP_LIST = s.ipRange(d.IP_RANGE_START,d.IP_RANGE_END); + }else{ + d.IP_LIST=d.IP_LIST.concat(s.ipRange(d.IP_RANGE_START,d.IP_RANGE_END)) + } + //check port + if(d.port.indexOf('-')>-1){ + d.port=d.port.split('-'); + d.PORT_RANGE_START = d.port[0]; + d.PORT_RANGE_END = d.port[1]; + d.PORT_LIST = s.portRange(d.PORT_RANGE_START,d.PORT_RANGE_END); + }else{ + d.PORT_LIST=d.port.split(',') + } + //check user name and pass + d.USERNAME=''; + if(d.user){ + d.USERNAME = d.user + } + d.PASSWORD=''; + if(d.pass){ + d.PASSWORD = d.pass + } + }) + d.cams=[] + d.IP_LIST.forEach(function(ip_entry,n) { + d.PORT_LIST.forEach(function(port_entry,nn) { + var device = new onvif.OnvifDevice({ + xaddr : 'http://' + ip_entry + ':' + port_entry + '/onvif/device_service', + user : d.USERNAME, + pass : d.PASSWORD + }) + device.init().then((info) => { + var data = { + f : 'onvif', + ip : ip_entry, + port : port_entry, + info : info + } + device.services.device.getSystemDateAndTime().then((date) => { + data.date = date + device.services.media.getStreamUri({ + ProfileToken : device.current_profile.token, + Protocol : 'RTSP' + }).then((stream) => { + data.uri = stream.data.GetStreamUriResponse.MediaUri.Uri + tx(data) + }).catch((error) => { +// console.log(error) + }); + }).catch((error) => { +// console.log(error) + }); + }).catch(function(error){ +// console.log(error) + }) + }); + }); +// tx({f:'onvif_end'}) + break; + } + }catch(er){ + s.systemLog('ERROR CATCH 1',er) + } + }else{ + tx({ok:false,msg:lang.NotAuthorizedText1}); + } + }); + // admin page socket functions + cn.on('super',function(d){ + if(!cn.init&&d.f=='init'){ + d.ok=s.superAuth({mail:d.mail,pass:d.pass},function(data){ + cn.uid=d.mail + cn.join('$'); + cn.ip=cn.request.connection.remoteAddress + s.log({ke:'$',mid:'$USER'},{type:lang['Websocket Connected'],msg:{for:lang['Superuser'],id:cn.uid,ip:cn.ip}}) + cn.init='super'; + cn.mail=d.mail; + s.tx({f:'init_success',mail:d.mail},cn.id); + }) + if(d.ok===false){ + cn.disconnect(); + } + }else{ + if(cn.mail&&cn.init=='super'){ + switch(d.f){ + case'logs': + switch(d.ff){ + case'delete': + s.sqlQuery('DELETE FROM Logs WHERE ke=?',[d.ke]) + break; + } + break; + case'system': + switch(d.ff){ + case'update': + s.ffmpegKill() + s.systemLog('Shinobi ordered to update',{by:cn.mail,ip:cn.ip,distro:d.distro}) + var updateProcess = spawn('sh',(__dirname+'/UPDATE.sh '+d.distro).split(' '),{detached: true}) + updateProcess.stderr.on('data',function(data){ + s.systemLog('Update Info',data.toString()) + }) + updateProcess.stdout.on('data',function(data){ + s.systemLog('Update Info',data.toString()) + }) + break; + case'restart': + d.check=function(x){return d.target.indexOf(x)>-1} + if(d.check('system')){ + s.systemLog('Shinobi ordered to restart',{by:cn.mail,ip:cn.ip}) + s.ffmpegKill() + exec('pm2 restart '+__dirname+'/camera.js') + } + if(d.check('cron')){ + s.systemLog('Shinobi CRON ordered to restart',{by:cn.mail,ip:cn.ip}) + exec('pm2 restart '+__dirname+'/cron.js') + } + if(d.check('logs')){ + s.systemLog('Flush PM2 Logs',{by:cn.mail,ip:cn.ip}) + exec('pm2 flush') + } + break; + case'configure': + s.systemLog('conf.json Modified',{by:cn.mail,ip:cn.ip,old:jsonfile.readFileSync(location.config)}) + jsonfile.writeFile(location.config,d.data,{spaces: 2},function(){ + s.tx({f:'save_configuration'},cn.id) + }) + break; + } + break; + case'accounts': + switch(d.ff){ + case'register': + if(d.form.mail!==''&&d.form.pass!==''){ + if(d.form.pass===d.form.password_again){ + s.sqlQuery('SELECT * FROM Users WHERE mail=?',[d.form.mail],function(err,r) { + if(r&&r[0]){ + //found address already exists + d.msg='Email address is in use.'; + s.tx({f:'error',ff:'account_register',msg:d.msg},cn.id) + }else{ + //create new + //user id + d.form.uid=s.gid(); + //check to see if custom key set + if(!d.form.ke||d.form.ke===''){ + d.form.ke=s.gid() + } + //write user to db + s.sqlQuery('INSERT INTO Users (ke,uid,mail,pass,details) VALUES (?,?,?,?,?)',[d.form.ke,d.form.uid,d.form.mail,s.md5(d.form.pass),d.form.details]) + s.tx({f:'add_account',details:d.form.details,ke:d.form.ke,uid:d.form.uid,mail:d.form.mail},'$'); + //init user + s.init('group',d.form) + } + }) + }else{ + d.msg=lang["Passwords Don't Match"]; + } + }else{ + d.msg=lang['Fields cannot be empty']; + } + if(d.msg){ + s.tx({f:'error',ff:'account_register',msg:d.msg},cn.id) + } + break; + case'edit': + if(d.form.pass&&d.form.pass!==''){ + if(d.form.pass===d.form.password_again){ + d.form.pass=s.md5(d.form.pass); + }else{ + s.tx({f:'error',ff:'account_edit',msg:lang["Passwords Don't Match"]},cn.id) + return + } + }else{ + delete(d.form.pass); + } + delete(d.form.password_again); + d.keys=Object.keys(d.form); + d.set=[]; + d.values=[]; + d.keys.forEach(function(v,n){ + if(d.set==='ke'||d.set==='password_again'||!d.form[v]){return} + d.set.push(v+'=?') + d.values.push(d.form[v]) + }) + d.values.push(d.account.mail) + s.sqlQuery('UPDATE Users SET '+d.set.join(',')+' WHERE mail=?',d.values,function(err,r) { + if(err){ + s.tx({f:'error',ff:'account_edit',msg:lang.AccountEditText1},cn.id) + return + } + s.tx({f:'edit_account',form:d.form,ke:d.account.ke,uid:d.account.uid},'$'); + delete(s.group[d.account.ke].init); + s.init('apps',d.account) + }) + break; + case'delete': + s.sqlQuery('DELETE FROM Users WHERE uid=? AND ke=? AND mail=?',[d.account.uid,d.account.ke,d.account.mail]) + s.sqlQuery('DELETE FROM API WHERE uid=? AND ke=?',[d.account.uid,d.account.ke]) + s.tx({f:'delete_account',ke:d.account.ke,uid:d.account.uid,mail:d.account.mail},'$'); + break; + } + break; + } + } + } + }) + // admin page socket functions + cn.on('a',function(d){ + if(!cn.init&&d.f=='init'){ + s.sqlQuery('SELECT * FROM Users WHERE auth=? AND uid=?',[d.auth,d.uid],function(err,r){ + if(r&&r[0]){ + r=r[0]; + if(!s.group[d.ke]){s.group[d.ke]={users:{}}} + if(!s.group[d.ke].users[d.auth]){s.group[d.ke].users[d.auth]={cnid:cn.id}} + try{s.group[d.ke].users[d.auth].details=JSON.parse(r.details)}catch(er){} + cn.join('ADM_'+d.ke); + cn.ke=d.ke; + cn.uid=d.uid; + cn.auth=d.auth; + cn.init='admin'; + }else{ + cn.disconnect(); + } + }) + }else{ + s.auth({auth:d.auth,ke:d.ke,id:d.id,ip:cn.request.connection.remoteAddress},function(user){ + if(!user.details.sub){ + switch(d.f){ + case'accounts': + switch(d.ff){ + case'edit': + d.keys=Object.keys(d.form); + d.condition=[]; + d.value=[]; + d.keys.forEach(function(v){ + d.condition.push(v+'=?') + d.value.push(d.form[v]) + }) + d.value=d.value.concat([d.ke,d.$uid]) + s.sqlQuery("UPDATE Users SET "+d.condition.join(',')+" WHERE ke=? AND uid=?",d.value) + s.tx({f:'edit_sub_account',ke:d.ke,uid:d.$uid,mail:d.mail,form:d.form},'ADM_'+d.ke); + break; + case'delete': + s.sqlQuery('DELETE FROM Users WHERE uid=? AND ke=? AND mail=?',[d.$uid,d.ke,d.mail]) + s.sqlQuery('DELETE FROM API WHERE uid=? AND ke=?',[d.$uid,d.ke]) + s.tx({f:'delete_sub_account',ke:d.ke,uid:d.$uid,mail:d.mail},'ADM_'+d.ke); + break; + } + break; + } + } + }) + } + }) + //functions for webcam recorder + cn.on('r',function(d){ + if(!cn.ke&&d.f==='init'){ + s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND auth=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) { + if(r&&r[0]){ + r=r[0] + cn.ke=d.ke,cn.uid=d.uid,cn.auth=d.auth; + if(!s.group[d.ke])s.group[d.ke]={}; + if(!s.group[d.ke].users)s.group[d.ke].users={}; + s.group[d.ke].users[d.auth]={cnid:cn.id,uid:r.uid,mail:r.mail,details:JSON.parse(r.details),logged_in_at:s.timeObject(new Date).format(),login_type:'Streamer'} + } + }) + }else{ + switch(d.f){ + case'monitor_chunk': + if(!s.group[d.ke]||!s.group[d.ke].mon[d.mid]){return} + if(s.group[d.ke].mon[d.mid].started!==1){s.tx({error:'Not Started'},cn.id);return false}; + s.group[d.ke].mon[d.mid].spawn.stdin.write(new Buffer(d.chunk, "binary")); + break; + case'monitor_frame': + if(!s.group[d.ke]||!s.group[d.ke].mon[d.mid]){return} + if(s.group[d.ke].mon[d.mid].started!==1){s.tx({error:'Not Started'},cn.id);return false}; + s.group[d.ke].mon[d.mid].spawn.stdin.write(d.frame); + break; + } + } + }) + //embed functions + cn.on('e', function (d) { + tx=function(z){if(!z.ke){z.ke=cn.ke;};cn.emit('f',z);} + switch(d.f){ + case'init': + if(!s.group[d.ke]||!s.group[d.ke].mon[d.id]||s.group[d.ke].mon[d.id].started===0){return false} + s.auth({auth:d.auth,ke:d.ke,id:d.id,ip:cn.request.connection.remoteAddress},function(user){ + cn.embedded=1; + cn.ke=d.ke; + if(!cn.mid){cn.mid={}} + cn.mid[d.id]={}; +// if(!s.group[d.ke].embed){s.group[d.ke].embed={}} +// if(!s.group[d.ke].embed[d.mid]){s.group[d.ke].embed[d.mid]={}} +// s.group[d.ke].embed[d.mid][cn.id]={} + + s.camera('watch_on',d,cn,tx) + cn.join('MON_'+d.id); + cn.join('MON_STREAM_'+d.id); + cn.join('DETECTOR_'+d.ke+d.id); + cn.join('STR_'+d.ke); + if(s.group[d.ke]&&s.group[d.ke].mon[d.id]&&s.group[d.ke].mon[d.id].watch){ + + tx({f:'monitor_watch_on',id:d.id,ke:d.ke},'MON_'+d.id) + s.tx({viewers:Object.keys(s.group[d.ke].mon[d.id].watch).length,ke:d.ke,id:d.id},'MON_'+d.id) + } + }); + break; + } + }) + //functions for retrieving cron announcements + cn.on('cron',function(d){ + if(d.f==='init'){ + if(config.cron.key){ + if(config.cron.key===d.cronKey){ + s.cron={started:moment(),last_run:moment(),id:cn.id}; + }else{ + cn.disconnect() + } + }else{ + s.cron={started:moment(),last_run:moment(),id:cn.id}; + } + }else{ + if(s.cron&&cn.id===s.cron.id){ + delete(d.cronKey) + switch(d.f){ + case'filters': + s.filterEvents(d.ff,d); + break; + case's.tx': + s.tx(d.data,d.to) + break; + case's.video': + s.video(d.data,d.file) + break; + case'start':case'end': + d.mid='_cron';s.log(d,{type:'cron',msg:d.msg}) + break; + default: + s.systemLog('CRON : ',d) + break; + } + }else{ + cn.disconnect() + } + } + }) + cn.on('disconnect', function () { + if(cn.socketVideoStream){ + cn.closeSocketVideoStream() + return + } + if(cn.ke){ + if(cn.monitor_watching){ + cn.monitor_count=Object.keys(cn.monitor_watching) + if(cn.monitor_count.length>0){ + cn.monitor_count.forEach(function(v){ + s.camera('watch_off',{id:v,ke:cn.monitor_watching[v].ke},s.cn(cn)) + }) + } + }else if(!cn.embedded){ + if(s.group[cn.ke].users[cn.auth].login_type==='Dashboard'){ + s.tx({f:'user_status_change',ke:cn.ke,uid:cn.uid,status:0}) + } + s.log({ke:cn.ke,mid:'$USER'},{type:lang['Websocket Disconnected'],msg:{mail:s.group[cn.ke].users[cn.auth].mail,id:cn.uid,ip:cn.ip}}) + delete(s.group[cn.ke].users[cn.auth]); + } + } + if(cn.pluginEngine){ + s.connectedPlugins[cn.pluginEngine].plugged=false + s.tx({f:'plugin_engine_unplugged',plug:cn.pluginEngine},'CPU') + delete(s.api[cn.pluginEngine]) + } + if(cn.cron){ + delete(s.cron); + } + if(cn.ocv){ + s.tx({f:'detector_unplugged',plug:s.ocv.plug},'CPU') + delete(s.ocv); + delete(s.api[cn.id]) + } + }) +}); +//Authenticator functions +s.api={}; +//auth handler +//params = parameters +//cb = callback +//res = response, only needed for express (http server) +//request = request, only needed for express (http server) +s.checkChildProxy = function(params,cb,res,req){ + if(s.group[params.ke] && s.group[params.ke].mon[params.id] && s.group[params.ke].mon[params.id].childNode){ + var url = 'http://' + s.group[params.ke].mon[params.id].childNode// + req.originalUrl + proxy.web(req, res, { target: url }) + }else{ + cb() + } +} +//auth handler +//params = parameters +//cb = callback +//res = response, only needed for express (http server) +//request = request, only needed for express (http server) +s.auth = function(params,cb,res,req){ + if(req){ + //express (http server) use of auth function + params.ip=req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress; + var failed=function(){ + if(!req.ret){req.ret={ok:false}} + req.ret.msg=lang['Not Authorized']; + res.end(s.s(req.ret, null, 3)); + } + }else{ + //socket.io use of auth function + var failed=function(){ + //maybe log + } + } + var clearAfterTime=function(){ + //remove temp key from memory + clearTimeout(s.api[params.auth].timeout) + s.api[params.auth].timeout=setTimeout(function(){ + delete(s.api[params.auth]) + },1000*60*5) + } + //check IP address of connecting user + var finish=function(user){ + if(s.api[params.auth].ip.indexOf('0.0.0.0')>-1||s.api[params.auth].ip.indexOf(params.ip)>-1){ + cb(user); + }else{ + failed(); + } + } + //check if auth key is user's temporary session key + if(s.group[params.ke]&&s.group[params.ke].users&&s.group[params.ke].users[params.auth]){ + s.group[params.ke].users[params.auth].permissions={}; + cb(s.group[params.ke].users[params.auth]); + }else{ + //check if key is already in memory to save query time + if(s.api[params.auth]&&s.api[params.auth].details){ + finish(s.api[params.auth]); + if(s.api[params.auth].timeout){ + clearAfterTime() + } + }else{ + //no key in memory, query db to see if key exists + //check if using username and password in plain text or md5 + if(params.username&¶ms.username!==''&¶ms.password&¶ms.password!==''){ + s.sqlQuery('SELECT * FROM Users WHERE mail=? AND (pass=? OR pass=?)',[params.username,params.password,s.md5(params.password)],function(err,r){ + if(r&&r[0]){ + r=r[0]; + r.ip='0.0.0.0'; + r.auth = s.gid(20); + params.auth = r.auth; + r.details=JSON.parse(r.details); + r.permissions = {}; + s.api[r.auth]=r; + clearAfterTime(); + finish(r); + }else{ + failed(); + } + }) + }else{ + //not using plain login + s.sqlQuery('SELECT * FROM API WHERE code=? AND ke=?',[params.auth,params.ke],function(err,r){ + if(r&&r[0]){ + r=r[0]; + s.api[params.auth]={ip:r.ip,uid:r.uid,ke:r.ke,permissions:JSON.parse(r.details),details:{}}; + s.sqlQuery('SELECT details FROM Users WHERE uid=? AND ke=?',[r.uid,r.ke],function(err,rr){ + if(rr&&rr[0]){ + rr=rr[0]; + try{ + s.api[params.auth].mail=rr.mail + s.api[params.auth].details=JSON.parse(rr.details) + s.api[params.auth].lang=s.getLanguageFile(s.api[params.auth].details.lang) + }catch(er){} + } + finish(s.api[params.auth]); + }) + }else{ + s.sqlQuery('SELECT * FROM Users WHERE auth=? AND ke=?',[params.auth,params.ke],function(err,r){ + if(r&&r[0]){ + r=r[0]; + r.ip='0.0.0.0' + s.api[params.auth]=r + s.api[params.auth].details=JSON.parse(r.details) + s.api[params.auth].permissions={} + clearAfterTime() + finish(r) + }else{ + failed(); + } + }) + } + }) + } + } + } +} +//super user authentication handler +s.superAuth=function(x,callback){ + req={}; + req.super=require(location.super); + req.super.forEach(function(v,n){ + if(x.md5===true){ + x.pass=s.md5(x.pass); + } + if(x.mail.toLowerCase()===v.mail.toLowerCase()&&x.pass===v.pass){ + req.found=1; + if(x.users===true){ + s.sqlQuery('SELECT * FROM Users WHERE details NOT LIKE ?',['%"sub"%'],function(err,r) { + callback({$user:v,users:r,config:config,lang:lang}) + }) + }else{ + callback({$user:v,config:config,lang:lang}) + } + } + }) + if(req.found!==1){ + return false; + }else{ + return true; + } +} +////Pages +app.enable('trust proxy'); +app.use('/libs',express.static(__dirname + '/web/libs')); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({extended: true})); +app.set('views', __dirname + '/web'); +app.set('view engine','ejs'); +//add template handler +if(config.renderPaths.handler!==undefined){require(__dirname+'/web/'+config.renderPaths.handler+'.js').addHandlers(s,app,io)} + +//readme +app.get('/:auth/logout/:ke/:id', function (req,res){ + if(s.group[req.params.ke]&&s.group[req.params.ke].users[req.params.auth]){ + delete(s.api[req.params.auth]); + delete(s.group[req.params.ke].users[req.params.auth]); + s.sqlQuery("UPDATE Users SET auth=? WHERE auth=? AND ke=? AND uid=?",['',req.params.auth,req.params.ke,req.params.id]) + res.end(s.s({ok:true,msg:'You have been logged out, session key is now inactive.'}, null, 3)) + }else{ + res.end(s.s({ok:false,msg:'This group key does not exist or this user is not logged in.'}, null, 3)) + } +}); +//main page +app.get(config.webPaths.index, function (req,res){ + res.render(config.renderPaths.index,{lang:lang,config:config,screen:'dashboard'},function(err,html){ + if(err){ + s.systemLog(err) + } + res.end(html) + }) +}); +//admin page +app.get(config.webPaths.admin, function (req,res){ + res.render(config.renderPaths.index,{lang:lang,config:config,screen:'admin'},function(err,html){ + if(err){ + s.systemLog(err) + } + res.end(html) + }) +}); +//super page +app.get(config.webPaths.super, function (req,res){ + res.render(config.renderPaths.index,{lang:lang,config:config,screen:'super'},function(err,html){ + if(err){ + s.systemLog(err) + } + res.end(html) + }) +}); +//update server +app.get('/:auth/update/:key', function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + req.fn=function(user){ + if(!config.updateKey){ + req.ret.msg=user.lang.updateKeyText1; + return; + } + if(req.params.key===config.updateKey){ + req.ret.ok=true; + exec('chmod +x '+__dirname+'/UPDATE.sh&&'+__dirname+'/UPDATE.sh',{detached: true}) + }else{ + req.ret.msg=user.lang.updateKeyText2; + } + res.end(s.s(req.ret, null, 3)); + } + s.auth(req.params,req.fn,res,req); +}); +//get user details by API key +app.get('/:auth/userInfo/:ke',function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + req.ret.ok=true + req.ret.user=user + res.end(s.s(req.ret, null, 3)); + },res,req); +}) +//register function +app.post('/:auth/register/:ke/:uid',function (req,res){ + req.resp={ok:false}; + res.setHeader('Content-Type', 'application/json'); + s.auth(req.params,function(user){ + s.sqlQuery('SELECT * FROM Users WHERE uid=? AND ke=? AND details NOT LIKE ? LIMIT 1',[req.params.uid,req.params.ke,'%"sub"%'],function(err,u) { + if(u&&u[0]){ + if(req.body.mail!==''&&req.body.pass!==''){ + if(req.body.pass===req.body.password_again){ + s.sqlQuery('SELECT * FROM Users WHERE mail=?',[req.body.mail],function(err,r) { + if(r&&r[0]){//found one exist + req.resp.msg='Email address is in use.'; + }else{//create new + req.resp.msg='New Account Created';req.resp.ok=true; + req.gid=s.gid(); + req.body.details='{"sub":"1","allmonitors":"1"}'; + s.sqlQuery('INSERT INTO Users (ke,uid,mail,pass,details) VALUES (?,?,?,?,?)',[req.params.ke,req.gid,req.body.mail,s.md5(req.body.pass),req.body.details]) + s.tx({f:'add_sub_account',details:req.body.details,ke:req.params.ke,uid:req.gid,mail:req.body.mail},'ADM_'+req.params.ke); + } + res.end(s.s(req.resp,null,3)); + }) + }else{ + req.resp.msg=user.lang['Passwords Don\'t Match']; + } + }else{ + req.resp.msg=user.lang['Fields cannot be empty']; + } + }else{ + req.resp.msg=user.lang['Not an Administrator Account']; + } + if(req.resp.msg){ + res.end(s.s(req.resp,null,3)); + } + }) + },res,req); +}) +//login function +s.deleteFactorAuth=function(r){ + delete(s.factorAuth[r.ke][r.uid]) + if(Object.keys(s.factorAuth[r.ke]).length===0){ + delete(s.factorAuth[r.ke]) + } +} +app.post(['/','/:screen'],function (req,res){ + req.ip=req.headers['cf-connecting-ip']||req.headers["CF-Connecting-IP"]||req.headers["'x-forwarded-for"]||req.connection.remoteAddress; + if(req.query.json=='true'){ + res.header("Access-Control-Allow-Origin",req.headers.origin); + } + req.renderFunction=function(focus,data){ + if(req.query.json=='true'){ + delete(data.config) + data.ok=true; + res.setHeader('Content-Type', 'application/json'); + res.end(s.s(data, null, 3)) + }else{ + data.screen=req.params.screen + res.render(focus,data,function(err,html){ + if(err){ + s.systemLog(err) + } + res.end(html) + }); + } + } + req.failed=function(board){ + if(req.query.json=='true'){ + res.setHeader('Content-Type', 'application/json'); + res.end(s.s({ok:false}, null, 3)) + }else{ + res.render(config.renderPaths.index,{failedLogin:true,lang:lang,config:config,screen:req.params.screen},function(err,html){ + if(err){ + s.systemLog(err) + } + res.end(html); + }); + } + req.logTo={ke:'$',mid:'$USER'} + req.logData={type:lang['Authentication Failed'],msg:{for:board,mail:req.body.mail,ip:req.ip}} + if(board==='super'){ + s.log(req.logTo,req.logData) + }else{ + s.sqlQuery('SELECT ke,uid,details FROM Users WHERE mail=?',[req.body.mail],function(err,r) { + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details); + r.lang=s.getLanguageFile(r.details.lang) + req.logData.id=r.uid + req.logData.type=r.lang['Authentication Failed'] + req.logTo.ke=r.ke + } + s.log(req.logTo,req.logData) + }) + } + } + req.fn=function(r){ + switch(req.body.function){ + case'cam': + s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND type=?',[r.ke,"dashcam"],function(err,rr){ + req.resp.mons=rr; + req.renderFunction(config.renderPaths.dashcam,{$user:req.resp,lang:r.lang,define:s.getDefinitonFile(r.details.lang)}); + }) + break; + case'streamer': + s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND type=?',[r.ke,"socket"],function(err,rr){ + req.resp.mons=rr; + req.renderFunction(config.renderPaths.streamer,{$user:req.resp,lang:r.lang,define:s.getDefinitonFile(r.details.lang)}); + }) + break; + case'admin': + if(!r.details.sub){ + s.sqlQuery('SELECT uid,mail,details FROM Users WHERE ke=? AND details LIKE \'%"sub"%\'',[r.ke],function(err,rr) { + s.sqlQuery('SELECT * FROM Monitors WHERE ke=?',[r.ke],function(err,rrr) { + req.renderFunction(config.renderPaths.admin,{$user:req.resp,$subs:rr,$mons:rrr,lang:r.lang,define:s.getDefinitonFile(r.details.lang)}); + }) + }) + }else{ + //not admin user + req.renderFunction(config.renderPaths.home,{$user:req.resp,config:config,lang:r.lang,define:s.getDefinitonFile(r.details.lang),addStorage:s.dir.addStorage,fs:fs,__dirname:__dirname}); + } + break; + default: + req.renderFunction(config.renderPaths.home,{$user:req.resp,config:config,lang:r.lang,define:s.getDefinitonFile(r.details.lang),addStorage:s.dir.addStorage,fs:fs,__dirname:__dirname}); + break; + } + s.log({ke:r.ke,mid:'$USER'},{type:r.lang['New Authentication Token'],msg:{for:req.body.function,mail:r.mail,id:r.uid,ip:req.ip}}) + // res.end(); + } + if(req.body.mail&&req.body.pass){ + req.default=function(){ + s.sqlQuery('SELECT * FROM Users WHERE mail=? AND pass=?',[req.body.mail,s.md5(req.body.pass)],function(err,r) { + req.resp={ok:false}; + if(!err&&r&&r[0]){ + r=r[0];r.auth=s.md5(s.gid()); + s.sqlQuery("UPDATE Users SET auth=? WHERE ke=? AND uid=?",[r.auth,r.ke,r.uid]) + req.resp={ok:true,auth_token:r.auth,ke:r.ke,uid:r.uid,mail:r.mail,details:r.details}; + r.details=JSON.parse(r.details); + r.lang=s.getLanguageFile(r.details.lang) + req.factorAuth=function(cb){ + if(r.details.factorAuth==="1"){ + if(!r.details.acceptedMachines||!(r.details.acceptedMachines instanceof Object)){ + r.details.acceptedMachines={} + } + if(!r.details.acceptedMachines[req.body.machineID]){ + req.complete=function(){ + s.factorAuth[r.ke][r.uid].info=req.resp; + clearTimeout(s.factorAuth[r.ke][r.uid].expireAuth) + s.factorAuth[r.ke][r.uid].expireAuth=setTimeout(function(){ + s.deleteFactorAuth(r) + },1000*60*15) + req.renderFunction(config.renderPaths.factorAuth,{$user:req.resp,lang:r.lang}) + } + if(!s.factorAuth[r.ke]){s.factorAuth[r.ke]={}} + if(!s.factorAuth[r.ke][r.uid]){ + s.factorAuth[r.ke][r.uid]={key:s.nid(),user:r} + r.mailOptions = { + from: '"ShinobiCCTV" ', + to: r.mail, + subject: r.lang['2-Factor Authentication'], + html: r.lang['Enter this code to proceed']+' '+s.factorAuth[r.ke][r.uid].key+'. '+r.lang.FactorAuthText1, + }; + nodemailer.sendMail(r.mailOptions, (error, info) => { + if (error) { + s.systemLog(r.lang.MailError,error) + req.fn(r) + return + } + req.complete() + }); + }else{ + req.complete() + } + }else{ + req.fn(r) + } + }else{ + req.fn(r) + } + } + if(r.details.sub){ + s.sqlQuery('SELECT details FROM Users WHERE ke=? AND details NOT LIKE ?',[r.ke,'%"sub"%'],function(err,rr) { + rr=rr[0]; + rr.details=JSON.parse(rr.details); + r.details.mon_groups=rr.details.mon_groups; + req.resp.details=JSON.stringify(r.details); + req.factorAuth() + }) + }else{ + req.factorAuth() + } + }else{ + req.failed(req.body.function) + } + }) + } + if(LdapAuth&&req.body.function==='ldap'&&req.body.key!==''){ + s.sqlQuery('SELECT * FROM Users WHERE ke=? AND details NOT LIKE ?',[req.body.key,'%"sub"%'],function(err,r) { + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details) + r.lang=s.getLanguageFile(r.details.lang) + if(r.details.use_ldap!=='0'&&r.details.ldap_enable==='1'&&r.details.ldap_url&&r.details.ldap_url!==''){ + req.mailArray={} + req.body.mail.split(',').forEach(function(v){ + v=v.split('=') + req.mailArray[v[0]]=v[1] + }) + if(!r.details.ldap_bindDN||r.details.ldap_bindDN===''){ + r.details.ldap_bindDN=req.body.mail + } + if(!r.details.ldap_bindCredentials||r.details.ldap_bindCredentials===''){ + r.details.ldap_bindCredentials=req.body.pass + } + if(!r.details.ldap_searchFilter||r.details.ldap_searchFilter===''){ + r.details.ldap_searchFilter=req.body.mail + if(req.mailArray.cn){ + r.details.ldap_searchFilter='cn='+req.mailArray.cn + } + if(req.mailArray.uid){ + r.details.ldap_searchFilter='uid='+req.mailArray.uid + } + }else{ + r.details.ldap_searchFilter=r.details.ldap_searchFilter.replace('{{username}}',req.body.mail) + } + if(!r.details.ldap_searchBase||r.details.ldap_searchBase===''){ + r.details.ldap_searchBase='dc=test,dc=com' + } + req.auth = new LdapAuth({ + url:r.details.ldap_url, + bindDN:r.details.ldap_bindDN, + bindCredentials:r.details.ldap_bindCredentials, + searchBase:r.details.ldap_searchBase, + searchFilter:'('+r.details.ldap_searchFilter+')', + reconnect:true + }); + req.auth.on('error', function (err) { + console.error('LdapAuth: ', err); + }); + + req.auth.authenticate(req.body.mail, req.body.pass, function(err, user) { + if(user){ + //found user + if(!user.uid){ + user.uid=s.gid() + } + req.resp={ + ke:req.body.key, + uid:user.uid, + auth:s.md5(s.gid()), + mail:user.mail, + pass:s.md5(req.body.pass), + details:JSON.stringify({ + sub:'1', + ldap:'1', + allmonitors:'1', + filter: {} + }) + } + user.post=[] + Object.keys(req.resp).forEach(function(v){ + user.post.push(req.resp[v]) + }) + s.log({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP Success'],msg:{user:user}}) + s.sqlQuery('SELECT * FROM Users WHERE ke=? AND mail=?',[req.body.key,user.cn],function(err,rr){ + if(rr&&rr[0]){ + //already registered + rr=rr[0] + req.resp=rr; + rr.details=JSON.parse(rr.details) + req.resp.lang=s.getLanguageFile(rr.details.lang) + s.log({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP User Authenticated'],msg:{user:user,shinobiUID:rr.uid}}) + s.sqlQuery("UPDATE Users SET auth=? WHERE ke=? AND uid=?",[req.resp.auth,req.resp.ke,rr.uid]) + }else{ + //new ldap login + s.log({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP User is New'],msg:{info:r.lang['Creating New Account'],user:user}}) + req.resp.lang=r.lang + s.sqlQuery('INSERT INTO Users (ke,uid,auth,mail,pass,details) VALUES (?,?,?,?,?,?)',user.post) + } + req.resp.details=JSON.stringify(req.resp.details) + req.resp.auth_token=req.resp.auth + req.resp.ok=true + req.fn(req.resp) + }) + return + } + s.log({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP Failed'],msg:{err:err}}) + //no user + req.default() + }); + + req.auth.close(function(err) { + + }) + }else{ + req.default() + } + }else{ + req.default() + } + }) + }else{ + if(req.body.function==='super'){ + if(!fs.existsSync(location.super)){ + res.end(lang.superAdminText) + return + } + req.ok=s.superAuth({mail:req.body.mail,pass:req.body.pass,users:true,md5:true},function(data){ + s.sqlQuery('SELECT * FROM Logs WHERE ke=? ORDER BY `time` DESC LIMIT 30',['$'],function(err,r) { + if(!r){ + r=[] + } + data.Logs=r; + fs.readFile(location.config,'utf8',function(err,file){ + data.plainConfig=JSON.parse(file) + req.renderFunction(config.renderPaths.super,data); + }) + }) + }) + if(req.ok===false){ + req.failed(req.body.function) + } + }else{ + req.default() + } + } + }else{ + if(req.body.machineID&&req.body.factorAuthKey){ + if(s.factorAuth[req.body.ke]&&s.factorAuth[req.body.ke][req.body.id]&&s.factorAuth[req.body.ke][req.body.id].key===req.body.factorAuthKey){ + if(s.factorAuth[req.body.ke][req.body.id].key===req.body.factorAuthKey){ + if(req.body.remember==="1"){ + req.details=JSON.parse(s.factorAuth[req.body.ke][req.body.id].info.details) + req.lang=s.getLanguageFile(req.details.lang) + if(!req.details.acceptedMachines||!(req.details.acceptedMachines instanceof Object)){ + req.details.acceptedMachines={} + } + if(!req.details.acceptedMachines[req.body.machineID]){ + req.details.acceptedMachines[req.body.machineID]={} + s.sqlQuery("UPDATE Users SET details=? WHERE ke=? AND uid=?",[s.s(req.details),req.body.ke,req.body.id]) + } + } + req.resp=s.factorAuth[req.body.ke][req.body.id].info + req.fn(s.factorAuth[req.body.ke][req.body.id].user) + }else{ + req.renderFunction(config.renderPaths.factorAuth,{$user:s.factorAuth[req.body.ke][req.body.id].info,lang:req.lang}); + res.end(); + } + }else{ + req.failed(lang['2-Factor Authentication']) + } + }else{ + req.failed(lang['2-Factor Authentication']) + } + } +}); +// Get HLS stream (m3u8) +app.get(['/:auth/hls/:ke/:id/:file','/:auth/hls/:ke/:id/:channel/:file'], function (req,res){ + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.fn=function(user){ + s.checkChildProxy(req.params,function(){ + req.dir=s.dir.streams+req.params.ke+'/'+req.params.id+'/' + if(req.params.channel){ + req.dir+='channel'+(parseInt(req.params.channel)+config.pipeAddition)+'/'+req.params.file; + }else{ + req.dir+=req.params.file; + } + res.on('finish',function(){res.end();}); + if (fs.existsSync(req.dir)){ + fs.createReadStream(req.dir).pipe(res); + }else{ + res.end(lang['File Not Found']) + } + },res,req) + } + s.auth(req.params,req.fn,res,req); +}); +//Get JPEG snap +app.get('/:auth/jpeg/:ke/:id/s.jpg', function(req,res){ + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + s.checkChildProxy(req.params,function(){ + if(user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors&&user.details.monitors.indexOf(req.params.id)===-1){ + res.end(user.lang['Not Permitted']) + return + } + req.dir=s.dir.streams+req.params.ke+'/'+req.params.id+'/s.jpg'; + res.writeHead(200, { + 'Content-Type': 'image/jpeg', + 'Cache-Control': 'no-cache', + 'Pragma': 'no-cache' + }); + res.on('finish',function(){res.end();delete(res)}); + if (fs.existsSync(req.dir)){ + fs.createReadStream(req.dir).pipe(res); + }else{ + fs.createReadStream(config.defaultMjpeg).pipe(res); + } + },res,req); + },res,req); +}); +//Get FLV stream +app.get(['/:auth/flv/:ke/:id/s.flv','/:auth/flv/:ke/:id/:channel/s.flv'], function(req,res) { + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + s.checkChildProxy(req.params,function(){ + var Emitter,chunkChannel + if(!req.params.channel){ + Emitter = s.group[req.params.ke].mon[req.params.id].emitter + chunkChannel = 'MAIN' + }else{ + Emitter = s.group[req.params.ke].mon[req.params.id].emitterChannel[parseInt(req.params.channel)+config.pipeAddition] + chunkChannel = parseInt(req.params.channel)+config.pipeAddition + } + if(s.group[req.params.ke].mon[req.params.id].firstStreamChunk[chunkChannel]){ + //variable name of contentWriter + var contentWriter + //set headers + res.setHeader('Content-Type', 'video/x-flv'); + res.setHeader('Access-Control-Allow-Origin','*'); + //write first frame on stream + res.write(s.group[req.params.ke].mon[req.params.id].firstStreamChunk[chunkChannel]) + //write new frames as they happen + Emitter.on('data',contentWriter=function(buffer){ + res.write(buffer) + }) + //remove contentWriter when client leaves + res.on('close', function () { + Emitter.removeListener('data',contentWriter) + }) + }else{ + res.setHeader('Content-Type', 'application/json'); + res.end(s.s({ok:false,msg:'FLV not started or not ready'},null,3)) + } + },res,req) + },res,req) +}) +//montage - stand alone squished view with gridstackjs +app.get(['/:auth/grid/:ke','/:auth/grid/:ke/:group'], function(req,res) { + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(user.permissions.get_monitors==="0"){ + res.end(user.lang['Not Permitted']) + return + } + + req.params.protocol=req.protocol; + req.sql='SELECT * FROM Monitors WHERE mode!=? AND mode!=? AND ke=?';req.ar=['stop','idle',req.params.ke]; + if(!req.params.id){ + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + } + }else{ + if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + }else{ + res.end(user.lang['There are no monitors that you can view with this account.']); + return; + } + } + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(req.params.group){ + var filteredByGroupCheck = {}; + var filteredByGroup = []; + r.forEach(function(v,n){ + var details = JSON.parse(r[n].details); + try{ + req.params.group.split('|').forEach(function(group){ + var groups = JSON.parse(details.groups); + if(groups.indexOf(group) > -1 && !filteredByGroupCheck[v.mid]){ + filteredByGroupCheck[v.mid] = true; + filteredByGroup.push(v) + } + }) + }catch(err){ + + } + }) + r = filteredByGroup; + } + r.forEach(function(v,n){ + if(s.group[v.ke]&&s.group[v.ke].mon[v.mid]&&s.group[v.ke].mon[v.mid].watch){ + r[n].currentlyWatching=Object.keys(s.group[v.ke].mon[v.mid].watch).length + } + r[n].subStream={} + var details = JSON.parse(r[n].details) + if(details.snap==='1'){ + r[n].subStream.jpeg = '/'+req.params.auth+'/jpeg/'+v.ke+'/'+v.mid+'/s.jpg' + } + if(details.stream_channels&&details.stream_channels!==''){ + try{ + details.stream_channels=JSON.parse(details.stream_channels) + r[n].channels=[] + details.stream_channels.forEach(function(b,m){ + var streamURL + switch(b.stream_type){ + case'mjpeg': + streamURL='/'+req.params.auth+'/mjpeg/'+v.ke+'/'+v.mid+'/'+m + break; + case'hls': + streamURL='/'+req.params.auth+'/hls/'+v.ke+'/'+v.mid+'/'+m+'/s.m3u8' + break; + case'h264': + streamURL='/'+req.params.auth+'/h264/'+v.ke+'/'+v.mid+'/'+m + break; + case'flv': + streamURL='/'+req.params.auth+'/flv/'+v.ke+'/'+v.mid+'/'+m+'/s.flv' + break; + case'mp4': + streamURL='/'+req.params.auth+'/mp4/'+v.ke+'/'+v.mid+'/'+m+'/s.mp4' + break; + } + r[n].channels.push(streamURL) + }) + }catch(err){ + s.log(req.params,{type:'Broken Monitor Object',msg:'Stream Channels Field is damaged. Skipping.'}) + } + } + }) + res.render(config.renderPaths.grid,{ + data:Object.assign(req.params,req.query), + baseUrl:req.protocol+'://'+req.hostname, + config:config, + lang:user.lang, + $user:user, + monitors:r + }); + }) + },res,req) +}); +//MJPEG feed +// if query string `full=true` is not present then it will load the MJPEG data directly and not the iframe ready page. +app.get(['/:auth/mjpeg/:ke/:id','/:auth/mjpeg/:ke/:id/:channel'], function(req,res) { + res.header("Access-Control-Allow-Origin",req.headers.origin); + if(req.query.full=='true'){ + res.render(config.renderPaths.mjpeg,{url:'/'+req.params.auth+'/mjpeg/'+req.params.ke+'/'+req.params.id}); + res.end() + }else{ + s.auth(req.params,function(user){ + s.checkChildProxy(req.params,function(){ + if(s.group[req.params.ke]&&s.group[req.params.ke].mon[req.params.id]){ + if(user.permissions.watch_stream==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){ + res.end(user.lang['Not Permitted']) + return + } + + var Emitter + if(!req.params.channel){ + Emitter = s.group[req.params.ke].mon[req.params.id].emitter + }else{ + Emitter = s.group[req.params.ke].mon[req.params.id].emitterChannel[parseInt(req.params.channel)+config.pipeAddition] + } + res.writeHead(200, { + 'Content-Type': 'multipart/x-mixed-replace; boundary=shinobi', + 'Cache-Control': 'no-cache', + 'Connection': 'keep-alive', + 'Pragma': 'no-cache' + }); + var contentWriter,content = fs.readFileSync(config.defaultMjpeg,'binary'); + res.write("--shinobi\r\n"); + res.write("Content-Type: image/jpeg\r\n"); + res.write("Content-Length: " + content.length + "\r\n"); + res.write("\r\n"); + res.write(content,'binary'); + res.write("\r\n"); + Emitter.on('data',contentWriter=function(d){ + content = d; + res.write(content,'binary'); + }) + res.on('close', function () { + Emitter.removeListener('data',contentWriter) + }); + }else{ + res.end(); + } + },res,req); + },res,req); + } +}); +//embed monitor +app.get(['/:auth/embed/:ke/:id','/:auth/embed/:ke/:id/:addon'], function (req,res){ + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.params.protocol=req.protocol; + s.auth(req.params,function(user){ + if(user.permissions.watch_stream==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){ + res.end(user.lang['Not Permitted']) + return + } + if(s.group[req.params.ke]&&s.group[req.params.ke].mon[req.params.id]){ + if(s.group[req.params.ke].mon[req.params.id].started===1){ + req.params.uid=user.uid; + res.render(config.renderPaths.embed,{data:req.params,baseUrl:req.protocol+'://'+req.hostname,config:config,lang:user.lang,mon:CircularJSON.parse(CircularJSON.stringify(s.group[req.params.ke].mon_conf[req.params.id]))}); + res.end() + }else{ + res.end(user.lang['Cannot watch a monitor that isn\'t running.']) + } + }else{ + res.end(user.lang['No Monitor Exists with this ID.']) + } + },res,req); +}); +// Get TV Channels (Monitor Streams) json +app.get(['/:auth/tvChannels/:ke','/:auth/tvChannels/:ke/:id','/get.php'], function (req,res){ + req.ret={ok:false}; + if(req.query.username&&req.query.password){ + req.params.username = req.query.username + req.params.password = req.query.password + } + var output = ['h264','hls','mp4'] + if(req.query.output&&req.query.output!==''){ + output = req.query.output.split(',') + output.forEach(function(type,n){ + if(type==='ts'){ + output[n]='h264' + if(output.indexOf('hls')===-1){ + output.push('hls') + } + } + }) + } + var isM3u8 = false; + if(req.query.type==='m3u8'||req.query.type==='m3u_plus'){ + //is m3u8 + isM3u8 = true; + }else{ + res.setHeader('Content-Type', 'application/json'); + } + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.fn=function(user){ + if(user.permissions.get_monitors==="0"){ + res.end(s.s([])) + return + } + if(!req.params.ke){ + req.params.ke = user.ke; + } + if(req.query.id&&!req.params.id){ + req.params.id = req.query.id; + } + req.sql='SELECT * FROM Monitors WHERE mode!=? AND ke=?';req.ar=['stop',req.params.ke]; + if(!req.params.id){ + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + } + }else{ + if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + }else{ + res.end('[]'); + return; + } + } + s.sqlQuery(req.sql,req.ar,function(err,r){ + var tvChannelMonitors = []; + r.forEach(function(v,n){ + var buildStreamURL = function(channelRow,type,channelNumber){ + var streamURL + if(channelNumber){channelNumber = '/'+channelNumber}else{channelNumber=''} + switch(type){ + case'mjpeg': + streamURL='/'+req.params.auth+'/mjpeg/'+v.ke+'/'+v.mid+channelNumber + break; + case'hls': + streamURL='/'+req.params.auth+'/hls/'+v.ke+'/'+v.mid+channelNumber+'/s.m3u8' + break; + case'h264': + streamURL='/'+req.params.auth+'/h264/'+v.ke+'/'+v.mid+channelNumber + break; + case'flv': + streamURL='/'+req.params.auth+'/flv/'+v.ke+'/'+v.mid+channelNumber+'/s.flv' + break; + case'mp4': + streamURL='/'+req.params.auth+'/mp4/'+v.ke+'/'+v.mid+channelNumber+'/s.ts' + break; + } + if(streamURL){ + if(!channelRow.streamsSortedByType[type]){ + channelRow.streamsSortedByType[type]=[] + } + channelRow.streamsSortedByType[type].push(streamURL) + channelRow.streams.push(streamURL) + } + return streamURL + } + var details = JSON.parse(r[n].details); + if(!details.tv_channel_id||details.tv_channel_id==='')details.tv_channel_id = 'temp_'+s.gid(5) + var channelRow = { + ke:v.ke, + mid:v.mid, + type:v.type, + groupTitle:details.tv_channel_group_title, + channel:details.tv_channel_id, + }; + if(details.snap==='1'){ + channelRow.snapshot = '/'+req.params.auth+'/jpeg/'+v.ke+'/'+v.mid+'/s.jpg' + } + channelRow.streams=[] + channelRow.streamsSortedByType={} + buildStreamURL(channelRow,details.stream_type) + if(details.stream_channels&&details.stream_channels!==''){ + details.stream_channels=JSON.parse(details.stream_channels) + details.stream_channels.forEach(function(b,m){ + buildStreamURL(channelRow,b.stream_type,m.toString()) + }) + } + if(details.tv_channel==='1'){ + tvChannelMonitors.push(channelRow) + } + }) + if(isM3u8){ + var m3u8 = '#EXTM3U'+'\n' + tvChannelMonitors.forEach(function(channelRow,n){ + output.forEach(function(type){ + if(channelRow.streamsSortedByType[type]){ + if(req.query.type==='m3u_plus'){ + m3u8 +='#EXTINF-1 tvg-id="'+channelRow.mid+'" tvg-name="'+channelRow.channel+'" tvg-logo="'+req.protocol+'://'+req.headers.host+channelRow.snapshot+'" group-title="'+channelRow.groupTitle+'",'+channelRow.channel+'\n' + }else{ + m3u8 +='#EXTINF:-1,'+channelRow.channel+' ('+type.toUpperCase()+') \n' + } + m3u8 += req.protocol+'://'+req.headers.host+channelRow.streamsSortedByType[type][0]+'\n' + } + }) + }) + res.end(m3u8) + }else{ + if(tvChannelMonitors.length===1){tvChannelMonitors=tvChannelMonitors[0];} + res.end(s.s(tvChannelMonitors, null, 3)); + } + }) + } + s.auth(req.params,req.fn,res,req); +}); +// Get monitors json +app.get(['/:auth/monitor/:ke','/:auth/monitor/:ke/:id'], function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.fn=function(user){ + if(user.permissions.get_monitors==="0"){ + res.end(s.s([])) + return + } + req.sql='SELECT * FROM Monitors WHERE ke=?';req.ar=[req.params.ke]; + if(!req.params.id){ + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + } + }else{ + if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + }else{ + res.end('[]'); + return; + } + } + s.sqlQuery(req.sql,req.ar,function(err,r){ + r.forEach(function(v,n){ + if(s.group[v.ke]&&s.group[v.ke].mon[v.mid]&&s.group[v.ke].mon[v.mid].watch){ + r[n].currentlyWatching=Object.keys(s.group[v.ke].mon[v.mid].watch).length + } + var buildStreamURL = function(type,channelNumber){ + var streamURL + if(channelNumber){channelNumber = '/'+channelNumber}else{channelNumber=''} + switch(type){ + case'mjpeg': + streamURL='/'+req.params.auth+'/mjpeg/'+v.ke+'/'+v.mid+channelNumber + break; + case'hls': + streamURL='/'+req.params.auth+'/hls/'+v.ke+'/'+v.mid+channelNumber+'/s.m3u8' + break; + case'h264': + streamURL='/'+req.params.auth+'/h264/'+v.ke+'/'+v.mid+channelNumber + break; + case'flv': + streamURL='/'+req.params.auth+'/flv/'+v.ke+'/'+v.mid+channelNumber+'/s.flv' + break; + case'mp4': + streamURL='/'+req.params.auth+'/mp4/'+v.ke+'/'+v.mid+channelNumber+'/s.mp4' + break; + } + if(streamURL){ + if(!r[n].streamsSortedByType[type]){ + r[n].streamsSortedByType[type]=[] + } + r[n].streamsSortedByType[type].push(streamURL) + r[n].streams.push(streamURL) + } + return streamURL + } + var details = JSON.parse(r[n].details); + if(!details.tv_channel_id||details.tv_channel_id==='')details.tv_channel_id = 'temp_'+s.gid(5) + if(details.snap==='1'){ + r[n].snapshot = '/'+req.params.auth+'/jpeg/'+v.ke+'/'+v.mid+'/s.jpg' + } + r[n].streams=[] + r[n].streamsSortedByType={} + buildStreamURL(details.stream_type) + if(details.stream_channels&&details.stream_channels!==''){ + details.stream_channels=JSON.parse(details.stream_channels) + details.stream_channels.forEach(function(b,m){ + buildStreamURL(b.stream_type,m.toString()) + }) + } + }) + if(r.length===1){r=r[0];} + res.end(s.s(r, null, 3)); + }) + } + s.auth(req.params,req.fn,res,req); +}); +// Get videos json +app.get(['/:auth/videos/:ke','/:auth/videos/:ke/:id'], function (req,res){ + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.video_view.indexOf(req.params.id)===-1){ + res.end(s.s([])) + return + } + req.sql='SELECT * FROM Videos WHERE ke=?';req.ar=[req.params.ke]; + req.count_sql='SELECT COUNT(*) FROM Videos WHERE ke=?';req.count_ar=[req.params.ke]; + if(req.query.archived=='1'){ + req.sql+=' AND details LIKE \'%"archived":"1"\'' + req.count_sql+=' AND details LIKE \'%"archived":"1"\'' + } + if(!req.params.id){ + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + req.count_sql+=' AND ('+req.or.join(' OR ')+')' + } + }else{ + if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + req.count_sql+=' and mid=?';req.count_ar.push(req.params.id) + }else{ + res.end('[]'); + return; + } + } + if(req.query.start||req.query.end){ + if(!req.query.startOperator||req.query.startOperator==''){ + req.query.startOperator='>=' + } + if(!req.query.endOperator||req.query.endOperator==''){ + req.query.endOperator='<=' + } + switch(true){ + case(req.query.start&&req.query.start!==''&&req.query.end&&req.query.end!==''): + req.query.start=req.query.start.replace('T',' ') + req.query.end=req.query.end.replace('T',' ') + req.sql+=' AND `time` '+req.query.startOperator+' ? AND `end` '+req.query.endOperator+' ?'; + req.count_sql+=' AND `time` '+req.query.startOperator+' ? AND `end` '+req.query.endOperator+' ?'; + req.ar.push(req.query.start) + req.ar.push(req.query.end) + req.count_ar.push(req.query.start) + req.count_ar.push(req.query.end) + break; + case(req.query.start&&req.query.start!==''): + req.query.start=req.query.start.replace('T',' ') + req.sql+=' AND `time` '+req.query.startOperator+' ?'; + req.count_sql+=' AND `time` '+req.query.startOperator+' ?'; + req.ar.push(req.query.start) + req.count_ar.push(req.query.start) + break; + case(req.query.end&&req.query.end!==''): + req.query.end=req.query.end.replace('T',' ') + req.sql+=' AND `end` '+req.query.endOperator+' ?'; + req.count_sql+=' AND `end` '+req.query.endOperator+' ?'; + req.ar.push(req.query.end) + req.count_ar.push(req.query.end) + break; + } + } + req.sql+=' ORDER BY `time` DESC'; + if(!req.query.limit||req.query.limit==''){ + req.query.limit='100' + } + if(req.query.limit!=='0'){ + req.sql+=' LIMIT '+req.query.limit + } + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(!r){ + res.end(s.s({total:0,limit:req.query.limit,skip:0,videos:[]}, null, 3)); + return + } + s.sqlQuery(req.count_sql,req.count_ar,function(err,count){ + s.video('linkBuild',r,req.params.auth) + if(req.query.limit.indexOf(',')>-1){ + req.skip=parseInt(req.query.limit.split(',')[0]) + req.query.limit=parseInt(req.query.limit.split(',')[0]) + }else{ + req.skip=0 + req.query.limit=parseInt(req.query.limit) + } + res.end(s.s({isUTC:config.useUTC,total:count[0]['COUNT(*)'],limit:req.query.limit,skip:req.skip,videos:r}, null, 3)); + }) + }) + },res,req); +}); +// Get events json (motion logs) +app.get(['/:auth/events/:ke','/:auth/events/:ke/:id','/:auth/events/:ke/:id/:limit','/:auth/events/:ke/:id/:limit/:start','/:auth/events/:ke/:id/:limit/:start/:end'], function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.video_view.indexOf(req.params.id)===-1){ + res.end(s.s([])) + return + } + req.sql='SELECT * FROM Events WHERE ke=?';req.ar=[req.params.ke]; + if(!req.params.id){ + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + } + }else{ + if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + }else{ + res.end('[]'); + return; + } + } + if(req.params.start&&req.params.start!==''){ + req.params.start=req.params.start.replace('T',' ') + if(req.params.end&&req.params.end!==''){ + req.params.end=req.params.end.replace('T',' ') + req.sql+=' AND `time` >= ? AND `time` <= ?'; + req.ar.push(decodeURIComponent(req.params.start)) + req.ar.push(decodeURIComponent(req.params.end)) + }else{ + req.sql+=' AND `time` >= ?'; + req.ar.push(decodeURIComponent(req.params.start)) + } + } + if(!req.params.limit||req.params.limit==''){req.params.limit=100} + req.sql+=' ORDER BY `time` DESC LIMIT '+req.params.limit+''; + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(err){ + err.sql=req.sql; + res.end(s.s(err, null, 3)); + return + } + if(!r){r=[]} + r.forEach(function(v,n){ + r[n].details=JSON.parse(v.details); + }) + res.end(s.s(r, null, 3)); + }) + },res,req); +}); +// Get logs json +app.get(['/:auth/logs/:ke','/:auth/logs/:ke/:id'], function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(user.permissions.get_logs==="0"){ + res.end(s.s([])) + return + } + req.sql='SELECT * FROM Logs WHERE ke=?';req.ar=[req.params.ke]; + if(!req.params.id){ + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + } + }else{ + if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1||req.params.id.indexOf('$')>-1){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + }else{ + res.end('[]'); + return; + } + } + if(!req.query.limit||req.query.limit==''){req.query.limit=50} + req.sql+=' ORDER BY `time` DESC LIMIT '+req.query.limit+''; + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(err){ + err.sql=req.sql; + res.end(s.s(err, null, 3)); + return + } + if(!r){r=[]} + r.forEach(function(v,n){ + r[n].info=JSON.parse(v.info) + }) + res.end(s.s(r, null, 3)); + }) + },res,req); +}); +// Get monitors online json +app.get('/:auth/smonitor/:ke', function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.fn=function(user){ + if(user.permissions.get_monitors==="0"){ + res.end(s.s([])) + return + } + req.sql='SELECT * FROM Monitors WHERE ke=?';req.ar=[req.params.ke]; + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + } + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(r&&r[0]){ + req.ar=[]; + r.forEach(function(v){ + if(s.group[req.params.ke]&&s.group[req.params.ke].mon[v.mid]&&s.group[req.params.ke].mon[v.mid].started===1){ + req.ar.push(v) + } + }) + }else{ + req.ar=[]; + } + res.end(s.s(req.ar, null, 3)); + }) + } + s.auth(req.params,req.fn,res,req); +}); +// Monitor Add,Edit,Delete +app.all(['/:auth/configureMonitor/:ke/:id','/:auth/configureMonitor/:ke/:id/:f'], function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(req.params.f!=='delete'){ + if(!req.body.data&&!req.query.data){ + req.ret.msg='No Monitor Data found.' + res.end(s.s(req.ret, null, 3)) + return + } + try{ + if(req.query.data){ + req.monitor=JSON.parse(req.query.data) + }else{ + req.monitor=JSON.parse(req.body.data) + } + }catch(er){ + if(!req.monitor){ + req.ret.msg=user.lang.monitorEditText1; + res.end(s.s(req.ret, null, 3)) + } + return + } + if(!user.details.sub||user.details.allmonitors==='1'||user.details.monitor_edit.indexOf(req.monitor.mid)>-1){ + if(req.monitor&&req.monitor.mid&&req.monitor.name){ + req.set=[],req.ar=[]; + req.monitor.mid=req.params.id.replace(/[^\w\s]/gi,'').replace(/ /g,''); + try{ + JSON.parse(req.monitor.details) + }catch(er){ + if(!req.monitor.details||!req.monitor.details.stream_type){ + req.ret.msg=user.lang.monitorEditText2; + res.end(s.s(req.ret, null, 3)) + return + }else{ + req.monitor.details=JSON.stringify(req.monitor.details) + } + } + req.monitor.ke=req.params.ke + req.logObject={details:JSON.parse(req.monitor.details),ke:req.params.ke,mid:req.params.id} + s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND mid=?',[req.monitor.ke,req.monitor.mid],function(er,r){ + req.tx={f:'monitor_edit',mid:req.monitor.mid,ke:req.monitor.ke,mon:req.monitor}; + if(r&&r[0]){ + req.tx.new=false; + Object.keys(req.monitor).forEach(function(v){ + if(req.monitor[v]&&req.monitor[v]!==''){ + req.set.push(v+'=?'),req.ar.push(req.monitor[v]); + } + }) + req.set=req.set.join(','); + req.ar.push(req.monitor.ke),req.ar.push(req.monitor.mid); + s.log(req.monitor,{type:'Monitor Updated',msg:'by user : '+user.uid}); + req.ret.msg=user.lang['Monitor Updated by user']+' : '+user.uid; + s.sqlQuery('UPDATE Monitors SET '+req.set+' WHERE ke=? AND mid=?',req.ar) + req.finish=1; + }else{ + if(!s.group[req.monitor.ke].init.max_camera||s.group[req.monitor.ke].init.max_camera==''||Object.keys(s.group[req.monitor.ke].mon).length <= parseInt(s.group[req.monitor.ke].init.max_camera)){ + req.tx.new=true; + req.st=[]; + Object.keys(req.monitor).forEach(function(v){ + if(req.monitor[v]&&req.monitor[v]!==''){ + req.set.push(v),req.st.push('?'),req.ar.push(req.monitor[v]); + } + }) + // req.set.push('ke'),req.st.push('?'),req.ar.push(req.monitor.ke); + req.set=req.set.join(','),req.st=req.st.join(','); + s.log(req.monitor,{type:'Monitor Added',msg:'by user : '+user.uid}); + req.ret.msg=user.lang['Monitor Added by user']+' : '+user.uid; + s.sqlQuery('INSERT INTO Monitors ('+req.set+') VALUES ('+req.st+')',req.ar) + req.finish=1; + }else{ + req.tx.f='monitor_edit_failed'; + req.tx.ff='max_reached'; + req.ret.msg=user.lang.monitorEditFailedMaxReached; + } + } + if(req.finish===1){ + req.monitor.details=JSON.parse(req.monitor.details) + req.ret.ok=true; + s.init(0,{mid:req.monitor.mid,ke:req.monitor.ke}); + s.group[req.monitor.ke].mon_conf[req.monitor.mid]=s.init('noReference',req.monitor); + if(req.monitor.mode==='stop'){ + s.camera('stop',req.monitor); + }else{ + s.camera('stop',req.monitor);setTimeout(function(){s.camera(req.monitor.mode,req.monitor);},5000) + }; + s.tx(req.tx,'STR_'+req.monitor.ke); + }; + s.tx(req.tx,'GRP_'+req.monitor.ke); + res.end(s.s(req.ret, null, 3)) + }) + }else{ + req.ret.msg=user.lang.monitorEditText1; + res.end(s.s(req.ret, null, 3)) + } + }else{ + req.ret.msg=user.lang['Not Permitted']; + res.end(s.s(req.ret, null, 3)) + } + }else{ + if(!user.details.sub||user.details.allmonitors==='1'||user.details.monitor_edit.indexOf(req.params.id)>-1){ + s.log(s.group[req.params.ke].mon_conf[req.params.id],{type:'Monitor Deleted',msg:'by user : '+user.uid}); + req.params.delete=1;s.camera('stop',req.params); + s.tx({f:'monitor_delete',uid:user.uid,mid:req.params.id,ke:req.params.ke},'GRP_'+req.params.ke); + s.sqlQuery('DELETE FROM Monitors WHERE ke=? AND mid=?',[req.params.ke,req.params.id]) + req.ret.ok=true; + req.ret.msg='Monitor Deleted by user : '+user.uid + res.end(s.s(req.ret, null, 3)) + } + } + }) +}) +app.get(['/:auth/monitor/:ke/:id/:f','/:auth/monitor/:ke/:id/:f/:ff','/:auth/monitor/:ke/:id/:f/:ff/:fff'], function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(user.permissions.control_monitors==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitor_edit.indexOf(req.params.id)===-1){ + res.end(user.lang['Not Permitted']) + return + } + if(req.params.f===''){req.ret.msg=user.lang.monitorGetText1;res.end(s.s(req.ret, null, 3));return} + if(req.params.f!=='stop'&&req.params.f!=='start'&&req.params.f!=='record'){ + req.ret.msg='Mode not recognized.'; + res.end(s.s(req.ret, null, 3)); + return; + } + s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND mid=?',[req.params.ke,req.params.id],function(err,r){ + if(r&&r[0]){ + r=r[0]; + if(req.query.reset==='1'||(s.group[r.ke]&&s.group[r.ke].mon_conf[r.mid].mode!==req.params.f)||req.query.fps&&(!s.group[r.ke].mon[r.mid].currentState||!s.group[r.ke].mon[r.mid].currentState.trigger_on)){ + if(req.query.reset!=='1'||!s.group[r.ke].mon[r.mid].trigger_timer){ + if(!s.group[r.ke].mon[r.mid].currentState)s.group[r.ke].mon[r.mid].currentState={} + s.group[r.ke].mon[r.mid].currentState.mode=r.mode.toString() + s.group[r.ke].mon[r.mid].currentState.fps=r.fps.toString() + if(!s.group[r.ke].mon[r.mid].currentState.trigger_on){ + s.group[r.ke].mon[r.mid].currentState.trigger_on=true + }else{ + s.group[r.ke].mon[r.mid].currentState.trigger_on=false + } + r.mode=req.params.f; + try{r.details=JSON.parse(r.details);}catch(er){} + if(req.query.fps){ + r.fps=parseFloat(r.details.detector_trigger_record_fps) + s.group[r.ke].mon[r.mid].currentState.detector_trigger_record_fps=r.fps + } + r.id=r.mid; + s.sqlQuery('UPDATE Monitors SET mode=? WHERE ke=? AND mid=?',[r.mode,r.ke,r.mid]); + s.group[r.ke].mon_conf[r.mid]=r; + s.tx({f:'monitor_edit',mid:r.mid,ke:r.ke,mon:r},'GRP_'+r.ke); + s.tx({f:'monitor_edit',mid:r.mid,ke:r.ke,mon:r},'STR_'+r.ke); + s.camera('stop',s.init('noReference',r)); + if(req.params.f!=='stop'){ + s.camera(req.params.f,s.init('noReference',r)); + } + req.ret.msg=user.lang['Monitor mode changed']+' : '+req.params.f; + }else{ + req.ret.msg=user.lang['Reset Timer']; + } + req.ret.cmd_at=s.formattedTime(new Date,'YYYY-MM-DD HH:mm:ss'); + req.ret.ok=true; + if(req.params.ff&&req.params.f!=='stop'){ + req.params.ff=parseFloat(req.params.ff); + clearTimeout(s.group[r.ke].mon[r.mid].trigger_timer) + switch(req.params.fff){ + case'day':case'days': + req.timeout=req.params.ff*1000*60*60*24 + break; + case'hr':case'hour':case'hours': + req.timeout=req.params.ff*1000*60*60 + break; + case'min':case'minute':case'minutes': + req.timeout=req.params.ff*1000*60 + break; + default://seconds + req.timeout=req.params.ff*1000 + break; + } + s.group[r.ke].mon[r.mid].trigger_timer=setTimeout(function(){ + delete(s.group[r.ke].mon[r.mid].trigger_timer) + s.sqlQuery('UPDATE Monitors SET mode=? WHERE ke=? AND mid=?',[s.group[r.ke].mon[r.mid].currentState.mode,r.ke,r.mid]); + r.neglectTriggerTimer=1; + r.mode=s.group[r.ke].mon[r.mid].currentState.mode; + r.fps=s.group[r.ke].mon[r.mid].currentState.fps; + s.camera('stop',s.init('noReference',r),function(){ + if(s.group[r.ke].mon[r.mid].currentState.mode!=='stop'){ + s.camera(s.group[r.ke].mon[r.mid].currentState.mode,s.init('noReference',r)); + } + s.group[r.ke].mon_conf[r.mid]=r; + }); + s.tx({f:'monitor_edit',mid:r.mid,ke:r.ke,mon:r},'GRP_'+r.ke); + s.tx({f:'monitor_edit',mid:r.mid,ke:r.ke,mon:r},'STR_'+r.ke); + },req.timeout); +// req.ret.end_at=s.formattedTime(new Date,'YYYY-MM-DD HH:mm:ss').add(req.timeout,'milliseconds'); + } + }else{ + req.ret.msg=user.lang['Monitor mode is already']+' : '+req.params.f; + } + }else{ + req.ret.msg=user.lang['Monitor or Key does not exist.']; + } + res.end(s.s(req.ret, null, 3)); + }) + },res,req); +}) +//get file from fileBin bin +app.get(['/:auth/fileBin/:ke','/:auth/fileBin/:ke/:id'],function (req,res){ + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.fn=function(user){ + req.sql='SELECT * FROM Files WHERE ke=?';req.ar=[req.params.ke]; + if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){ + try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){} + req.or=[]; + user.details.monitors.forEach(function(v,n){ + req.or.push('mid=?');req.ar.push(v) + }) + req.sql+=' AND ('+req.or.join(' OR ')+')' + }else{ + if(req.params.id&&(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1)){ + req.sql+=' and mid=?';req.ar.push(req.params.id) + } + } + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(!r){ + r=[] + }else{ + r.forEach(function(v){ + v.details=JSON.parse(v.details) + v.href='/'+req.params.auth+'/fileBin/'+req.params.ke+'/'+req.params.id+'/'+v.details.year+'/'+v.details.month+'/'+v.details.day+'/'+v.name; + }) + } + res.end(s.s(r, null, 3)); + }) + } + s.auth(req.params,req.fn,res,req); +}); +//get file from fileBin bin +app.get('/:auth/fileBin/:ke/:id/:year/:month/:day/:file', function (req,res){ + res.header("Access-Control-Allow-Origin",req.headers.origin); + req.fn=function(user){ + req.failed=function(){ + res.end(user.lang['File Not Found']) + } + if (!s.group[req.params.ke].fileBin[req.params.id+'/'+req.params.file]){ + s.sqlQuery('SELECT * FROM Files WHERE ke=? AND mid=? AND name=?',[req.params.ke,req.params.id,req.params.file],function(err,r){ + if(r&&r[0]){ + r=r[0] + r.details=JSON.parse(r.details) + req.dir=s.dir.fileBin+req.params.ke+'/'+req.params.id+'/'+r.details.year+'/'+r.details.month+'/'+r.details.day+'/'+req.params.file; + if(fs.existsSync(req.dir)){ + res.on('finish',function(){res.end();}); + fs.createReadStream(req.dir).pipe(res); + }else{ + req.failed() + } + }else{ + req.failed() + } + }) + }else{ + res.end(user.lang['Please Wait for Completion']) + } + } + s.auth(req.params,req.fn,res,req); +}); +// Get video file +app.get('/:auth/videos/:ke/:id/:file', function (req,res){ + s.auth(req.params,function(user){ + if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){ + res.end(user.lang['Not Permitted']) + return + } + var filename = s.nameToTime(req.params.file) + if(req.query.isUTC === 'true'){ + filename = s.utcToLocal(filename) + } + s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND mid=? AND time=?',[req.params.ke,req.params.id,filename],function(err,r){ + if(r&&r[0]){ + req.dir=s.video('getDir',r[0])+req.params.file + if (fs.existsSync(req.dir)){ + req.ext=req.params.file.split('.')[1]; + var total = fs.statSync(req.dir).size; + if (req.headers['range']) { + var range = req.headers.range; + var parts = range.replace(/bytes=/, "").split("-"); + var partialstart = parts[0]; + var partialend = parts[1]; + + var start = parseInt(partialstart, 10); + var end = partialend ? parseInt(partialend, 10) : total-1; + var chunksize = (end-start)+1; + var file = fs.createReadStream(req.dir, {start: start, end: end}); + req.headerWrite={ 'Content-Range': 'bytes ' + start + '-' + end + '/' + total, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize, 'Content-Type': 'video/'+req.ext } + req.writeCode=206 + } else { + req.headerWrite={ 'Content-Length': total, 'Content-Type': 'video/'+req.ext}; + var file=fs.createReadStream(req.dir) + req.writeCode=200 + } + if(req.query.downloadName){ + req.headerWrite['content-disposition']='attachment; filename="'+req.query.downloadName+'"'; + } + res.writeHead(req.writeCode,req.headerWrite); + file.on('close',function(){ + res.end(); + }) + file.pipe(res); + }else{ + res.end(user.lang['File Not Found in Filesystem']) + } + }else{ + res.end(user.lang['File Not Found in Database']) + } + }) + },res,req); +}); +//motion trigger +app.get('/:auth/motion/:ke/:id', function (req,res){ + s.auth(req.params,function(user){ + if(req.query.data){ + try{ + var d={id:req.params.id,ke:req.params.ke,details:JSON.parse(req.query.data)}; + }catch(err){ + res.end('Data Broken',err); + return; + } + }else{ + res.end('No Data'); + return; + } + if(!d.ke||!d.id||!s.group[d.ke]){ + res.end(user.lang['No Group with this key exists']); + return; + } + s.camera('motion',d,function(){ + res.end(user.lang['Trigger Successful']) + }); + },res,req); +}) +//hookTester trigger +app.get('/:auth/hookTester/:ke/:id', function (req,res){ + res.setHeader('Content-Type', 'application/json'); + s.auth(req.params,function(user){ + s.log(req.params,{type:'Test',msg:'Hook Test'}) + res.end(s.s({ok:true},null,3)) + },res,req); +}) +//control trigger +app.get('/:auth/control/:ke/:id/:direction', function (req,res){ + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + s.camera('control',req.params,function(resp){ + res.end(s.s(resp,null,3)) + }); + },res,req); +}) +//modify video file +app.get(['/:auth/videos/:ke/:id/:file/:mode','/:auth/videos/:ke/:id/:file/:mode/:f'], function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.video_delete.indexOf(req.params.id)===-1){ + res.end(user.lang['Not Permitted']) + return + } + var filename = s.nameToTime(req.params.file) + if(req.query.isUTC === 'true'){ + filename = s.utcToLocal(filename) + } + req.sql='SELECT * FROM Videos WHERE ke=? AND mid=? AND time=?'; + req.ar=[req.params.ke,req.params.id,filename]; + s.sqlQuery(req.sql,req.ar,function(err,r){ + if(r&&r[0]){ + r=r[0];r.filename=s.formattedTime(r.time)+'.'+r.ext; + switch(req.params.mode){ + case'fix': + req.ret.ok=true; + s.video('fix',r) + break; + case'status': + req.params.f=parseInt(req.params.f) + if(isNaN(req.params.f)||req.params.f===0){ + req.ret.msg='Not a valid value.'; + }else{ + req.ret.ok=true; + s.sqlQuery('UPDATE Videos SET status=? WHERE ke=? AND mid=? AND time=?',[req.params.f,req.params.ke,req.params.id,filename]) + s.tx({f:'video_edit',status:req.params.f,filename:r.filename,mid:r.mid,ke:r.ke,time:s.nameToTime(r.filename),end:s.formattedTime(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+r.ke); + } + break; + case'delete': + req.ret.ok=true; + s.video('delete',r) + break; + default: + req.ret.msg=user.lang.modifyVideoText1; + break; + } + }else{ + req.ret.msg=user.lang['No such file']; + } + res.end(s.s(req.ret, null, 3)); + }) + },res,req); +}) +//ffmpeg pushed stream in here to make a pipe +app.all(['/streamIn/:ke/:id','/streamIn/:ke/:id/:feed'], function (req, res) { + var checkOrigin = function(search){return req.headers.host.indexOf(search)>-1} + if(checkOrigin('127.0.0.1')){ + if(!req.params.feed){req.params.feed='1'} + if(!s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed]){ + s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed] = new events.EventEmitter().setMaxListeners(0) + } + //req.params.feed = Feed Number + res.connection.setTimeout(0); + req.on('data', function(buffer){ + s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed].emit('data',buffer) + }); + req.on('end',function(){ +// console.log('streamIn closed',req.params); + }); + }else{ + res.end('Local connection is only allowed.') + } +}) +//MP4 Stream +app.get(['/:auth/mp4/:ke/:id/:channel/s.mp4','/:auth/mp4/:ke/:id/s.mp4','/:auth/mp4/:ke/:id/:channel/s.ts','/:auth/mp4/:ke/:id/s.ts'], function (req, res) { + s.auth(req.params,function(user){ + if(!s.group[req.params.ke] || !s.group[req.params.ke].mon[req.params.id]){ + res.status(404); + res.end('404 : Monitor not found'); + return + } + s.checkChildProxy(req.params,function(){ + var Channel = 'MAIN' + if(req.params.channel){ + Channel = parseInt(req.params.channel)+config.pipeAddition + } + var mp4frag = s.group[req.params.ke].mon[req.params.id].mp4frag[Channel]; + var errorMessage = 'MP4 Stream is not enabled' + if(!mp4frag){ + res.status(503); + res.end('503 : initialization : '+errorMessage); + }else{ + var init = mp4frag.initialization; + if (!init) { + res.status(503); + res.end('404 : Not Found : '+errorMessage); + } else { + res.locals.mp4frag = mp4frag + res.set('Access-Control-Allow-Origin', '*') + res.set('Connection', 'close') + res.set('Cache-Control', 'private, no-cache, no-store, must-revalidate') + res.set('Expires', '-1') + res.set('Pragma', 'no-cache') + res.set('Content-Type', 'video/mp4') + res.status(200); + res.write(init); + mp4frag.pipe(res); + res.on('close', () => { + mp4frag.unpipe(res); + }); + } + } + },res,req); + },res,req); +}); +//simulate RTSP over HTTP +app.get([ + '/:auth/mpegts/:ke/:id/:feed/:file', + '/:auth/mpegts/:ke/:id/:feed/', + '/:auth/h264/:ke/:id/:feed/:file', + '/:auth/h264/:ke/:id/:feed', + '/:auth/h264/:ke/:id' +], function (req, res) { + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + s.checkChildProxy(req.params,function(){ + if(!req.query.feed){req.query.feed='1'} + var Emitter + if(!req.params.feed){ + Emitter = s.group[req.params.ke].mon[req.params.id].streamIn[req.query.feed] + }else{ + Emitter = s.group[req.params.ke].mon[req.params.id].emitterChannel[parseInt(req.params.feed)+config.pipeAddition] + } + s.init('streamIn',req.params) + var contentWriter + var date = new Date(); + res.writeHead(200, { + 'Date': date.toUTCString(), + 'Connection': 'keep-alive', + 'Cache-Control': 'no-cache', + 'Pragma': 'no-cache', + 'Content-Type': 'video/mp4', + 'Server': 'Shinobi H.264 Test Stream', + }); + Emitter.on('data',contentWriter=function(buffer){ + res.write(buffer) + }) + res.on('close', function () { + Emitter.removeListener('data',contentWriter) + }) + },res,req); + },res,req); +}); +//FFprobe by API +app.get('/:auth/probe/:ke',function (req,res){ + req.ret={ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + switch(req.query.action){ +// case'stop': +// exec('kill -9 '+user.ffprobe.pid,{detatched: true}) +// break; + default: + if(!req.query.url){ + req.ret.error = 'Missing URL' + res.end(s.s(req.ret, null, 3)); + return + } + if(user.ffprobe){ + req.ret.error = 'Account is already probing' + res.end(s.s(req.ret, null, 3)); + return + } + user.ffprobe=1; + if(req.query.flags==='default'){ + req.query.flags = '-v quiet -print_format json -show_format -show_streams' + }else{ + if(!req.query.flags){ + req.query.flags = '' + } + } + req.probeCommand = s.splitForFFPMEG(req.query.flags+' -i '+req.query.url).join(' ') + exec('ffprobe '+req.probeCommand+' | echo ',function(err,stdout,stderr){ + delete(user.ffprobe) + if(err){ + req.ret.error=(err) + }else{ + req.ret.ok=true + req.ret.result = stdout+stderr + } + req.ret.probe = req.probeCommand + res.end(s.s(req.ret, null, 3)); + }) + break; + } + },res,req); +}) +//ONVIF requesting with Shinobi API structure +app.all(['/:auth/onvif/:ke/:id/:action','/:auth/onvif/:ke/:id/:service/:action'],function (req,res){ + var response = {ok:false}; + res.setHeader('Content-Type', 'application/json'); + res.header("Access-Control-Allow-Origin",req.headers.origin); + s.auth(req.params,function(user){ + var errorMessage = function(msg,error){ + response.ok = false + response.msg = msg + response.error = error + res.end(s.s(response,null,3)) + } + var actionCallback = function(onvifActionResponse){ + response.ok = true + if(onvifActionResponse.data){ + response.responseFromDevice = onvifActionResponse.data + }else{ + response.responseFromDevice = onvifActionResponse + } + if(onvifActionResponse.soap)response.soap = onvifActionResponse.soap + res.end(s.s(response,null,3)) + } + var isEmpty = function(obj) { + for(var key in obj) { + if(obj.hasOwnProperty(key)) + return false; + } + return true; + } + var doAction = function(Camera){ + var completeAction = function(command){ + if(command.then){ + command.then(actionCallback).catch(function(error){ + errorMessage('Device responded with an error',error) + }) + }else if(command){ + response.ok = true + response.repsonseFromDevice = command + res.end(s.s(response,null,3)) + }else{ + response.error = 'Big Errors, Please report it to Shinobi Development' + res.end(s.s(response,null,3)) + } + } + var action + if(req.params.service){ + if(Camera.services[req.params.service] === undefined){ + return errorMessage('This is not an available service. Please use one of the following : '+Object.keys(Camera.services).join(', ')) + } + if(Camera.services[req.params.service] === null){ + return errorMessage('This service is not activated. Maybe you are not connected through ONVIF. You can test by attempting to use the "Control" feature with ONVIF in Shinobi.') + } + action = Camera.services[req.params.service][req.params.action] + }else{ + action = Camera[req.params.action] + } + if(!action || typeof action !== 'function'){ + errorMessage(req.params.action+' is not an available ONVIF function. See https://github.com/futomi/node-onvif for functions.') + }else{ + var argNames = s.getFunctionParamNames(action) + var options + var command + if(argNames[0] === 'options' || argNames[0] === 'params'){ + options = {} + if(req.query.options){ + var jsonRevokedText = 'JSON not formated correctly' + try{ + options = JSON.parse(req.query.options) + }catch(err){ + return errorMessage(jsonRevokedText,err) + } + }else if(req.body.options){ + try{ + options = JSON.parse(req.body.options) + }catch(err){ + return errorMessage(jsonRevokedText,err) + } + }else if(req.query.params){ + try{ + options = JSON.parse(req.query.params) + }catch(err){ + return errorMessage(jsonRevokedText,err) + } + }else if(req.body.params){ + try{ + options = JSON.parse(req.body.params) + }catch(err){ + return errorMessage(jsonRevokedText,err) + } + } + } + if(req.params.service){ + command = Camera.services[req.params.service][req.params.action](options) + }else{ + command = Camera[req.params.action](options) + } + completeAction(command) + } + } + if(!s.group[req.params.ke].mon[req.params.id].onvifConnection){ + //prepeare onvif connection + var controlURL + var monitorConfig = s.group[req.params.ke].mon_conf[req.params.id] + if(!monitorConfig.details.control_base_url||monitorConfig.details.control_base_url===''){ + controlURL = s.init('url_no_path',monitorConfig) + }else{ + controlURL = monitorConfig.details.control_base_url + } + var controlURLOptions = s.camera('buildOptionsFromUrl',controlURL,monitorConfig) + //create onvif connection + s.group[req.params.ke].mon[req.params.id].onvifConnection = new onvif.OnvifDevice({ + xaddr : 'http://' + controlURLOptions.host + ':' + controlURLOptions.port + '/onvif/device_service', + user : controlURLOptions.username, + pass : controlURLOptions.password + }) + var device = s.group[req.params.ke].mon[req.params.id].onvifConnection + device.init().then((info) => { + if(info)doAction(device) + }).catch(function(error){ + return errorMessage('Device responded with an error',error) + }) + }else{ + doAction(s.group[req.params.ke].mon[req.params.id].onvifConnection) + } + },res,req); +}) +s.cpuUsage=function(e){ + k={} + switch(s.platform){ + case'win32': + k.cmd="@for /f \"skip=1\" %p in ('wmic cpu get loadpercentage') do @echo %p%" + break; + case'darwin': + k.cmd="ps -A -o %cpu | awk '{s+=$1} END {print s}'"; + break; + case'linux': + k.cmd='LANG=C top -b -n 2 | grep "^'+config.cpuUsageMarker+'" | awk \'{print $2}\' | tail -n1'; + break; + } + if(config.customCpuCommand){ + exec(config.customCpuCommand,{encoding:'utf8',detached: true},function(err,d){ + if(s.isWin===true) { + d = d.replace(/(\r\n|\n|\r)/gm, "").replace(/%/g, "") + } + e(d) + }); + } else if(k.cmd){ + exec(k.cmd,{encoding:'utf8',detached: true},function(err,d){ + if(s.isWin===true){ + d=d.replace(/(\r\n|\n|\r)/gm,"").replace(/%/g,"") + } + e(d) + }); + } else{ + e(0) + } +} +s.ramUsage=function(e){ + k={} + switch(s.platform){ + case'win32': + k.cmd = "wmic OS get FreePhysicalMemory /Value" + break; + case'darwin': + k.cmd = "vm_stat | awk '/^Pages free: /{f=substr($3,1,length($3)-1)} /^Pages active: /{a=substr($3,1,length($3-1))} /^Pages inactive: /{i=substr($3,1,length($3-1))} /^Pages speculative: /{s=substr($3,1,length($3-1))} /^Pages wired down: /{w=substr($4,1,length($4-1))} /^Pages occupied by compressor: /{c=substr($5,1,length($5-1)); print ((a+w)/(f+a+i+w+s+c))*100;}'" + break; + default: + k.cmd = "LANG=C free | grep Mem | awk '{print $4/$2 * 100.0}'"; + break; + } + if(k.cmd){ + exec(k.cmd,{encoding:'utf8',detached: true},function(err,d){ + if(s.isWin===true){ + d=(parseInt(d.split('=')[1])/(s.totalmem/1000))*100 + } + e(d) + }); + }else{ + e(0) + } +} +//check disk space every 20 minutes +if(config.autoDropCache===true){ + setInterval(function(){ + exec('echo 3 > /proc/sys/vm/drop_caches',{detached: true}) + },60000*20); +} +s.beat=function(){ + setTimeout(s.beat, 8000); + io.sockets.emit('ping',{beat:1}); +} +s.beat(); +s.processReady = function(){ + s.systemLog(lang.startUpText5) + process.send('ready') +} +//setup Master for childNodes +if(config.childNodes.enabled === true && config.childNodes.mode === 'master'){ + s.childNodes = {}; + var childNodeHTTP = express(); + var childNodeServer = http.createServer(app); + var childNodeWebsocket = new (require('socket.io'))() + childNodeServer.listen(config.childNodes.port,config.bindip,function(){ + console.log(lang.Shinobi+' - CHILD NODE PORT : '+config.childNodes.port); + }); + childNodeWebsocket.attach(childNodeServer); + //send data to child node function (experimental) + s.cx = function(z,y,x){if(!z.mid && !z.d){ + var err = new Error(); + console.log(err.stack); + };if(x){return x.broadcast.to(y).emit('c',z)};childNodeWebsocket.to(y).emit('c',z);} + //child Node Websocket + childNodeWebsocket.on('connection', function (cn) { + //functions for dispersing work to child servers; + cn.on('c',function(d){ + if(config.childNodes.key.indexOf(d.socketKey) > -1){ + if(!cn.shinobi_child&&d.f=='init'){ + cn.ip = cn.request.connection.remoteAddress.replace('::ffff:','')+':'+d.port + cn.shinobi_child = 1 + tx = function(z){ + cn.emit('c',z) + } + if(!s.childNodes[cn.ip]){ + s.childNodes[cn.ip] = {} + }; + s.childNodes[cn.ip].cnid = cn.id + s.childNodes[cn.ip].cpu = 0 + s.childNodes[cn.ip].activeCameras = {} + tx({ + f : 'init_success', + childNodes : s.childNodes + }); + }else{ + switch(d.f){ + case'cpu': + s.childNodes[cn.ip].cpu = d.cpu; + break; + case'sql': + s.sqlQuery(d.query,d.values,function(err,rows){ + cn.emit('c',{f:'sqlCallback',rows:rows,err:err,callbackId:d.callbackId}); + }); + break; + case'camera': + s.camera(d.mode,d.data) + break; + case's.tx': + s.tx(d.data,d.to) + break; + case's.log': + if(!d.mon || !d.data)return console.log('LOG DROPPED',d.mon,d.data); + s.log(d.mon,d.data) + break; + case'created_file_chunk': + if(!s.group[d.ke].mon[d.mid].childNodeStreamWriters[d.filename]){ + d.dir = s.video('getDir',s.group[d.ke].mon_conf[d.mid]) + s.group[d.ke].mon[d.mid].childNodeStreamWriters[d.filename] = fs.createWriteStream(d.dir+d.filename) + } + s.group[d.ke].mon[d.mid].childNodeStreamWriters[d.filename].write(d.chunk) + break; + case'created_file': + if(!s.group[d.ke].mon[d.mid].childNodeStreamWriters[d.filename]){ + return console.log('FILE NOT EXIST') + } + s.group[d.ke].mon[d.mid].childNodeStreamWriters[d.filename].end(); + tx({ + f:'delete', + file:d.filename, + ke:d.ke, + mid:d.mid + }); + s.txWithSubPermissions({ + f:'video_build_success', + hrefNoAuth:'/videos/'+d.ke+'/'+d.mid+'/'+d.filename, + filename:d.filename, + mid:d.mid, + ke:d.ke, + time:s.timeObject(d.startTime).format(), + size:d.filesize, + end:s.timeObject(d.endTime).format() + },'GRP_'+d.ke,'video_view'); + clearTimeout(s.group[d.ke].mon[d.mid].checker) + clearTimeout(s.group[d.ke].mon[d.mid].checkStream) + break; + } + } + } + }) + cn.on('disconnect',function(){ + if(s.childNodes[cn.ip]){ + var activeCameraKeys = Object.keys(s.childNodes[cn.ip].activeCameras) + activeCameraKeys.forEach(function(key){ + var monitor = s.childNodes[cn.ip].activeCameras[key] + s.camera('stop',s.init('noReference',monitor)) + delete(s.group[monitor.ke].mon[monitor.mid].childNode) + delete(s.group[monitor.ke].mon[monitor.mid].childNodeId) + setTimeout(function(){ + s.camera(monitor.mode,s.init('noReference',monitor)) + },1300) + }) + delete(s.childNodes[cn.ip]); + } + }) + }) +}else +//setup Child for childNodes +if(config.childNodes.enabled === true && config.childNodes.mode === 'child' && config.childNodes.host){ + s.connected = false; + childIO = require('socket.io-client')('ws://'+config.childNodes.host); + s.cx = function(x){x.socketKey = config.childNodes.key;childIO.emit('c',x)} + s.tx = function(x,y){s.cx({f:'s.tx',data:x,to:y})} + s.log = function(x,y){s.cx({f:'s.log',mon:x,data:y})} + s.queuedSqlCallbacks = {} + s.sqlQuery = function(query,values,onMoveOn){ + var callbackId = s.gid() + if(!values){values=[]} + if(typeof values === 'function'){ + var onMoveOn = values; + var values = []; + } + if(typeof onMoveOn !== 'function'){onMoveOn=function(){}} + s.queuedSqlCallbacks[callbackId] = onMoveOn + s.cx({f:'sql',query:query,values:values,callbackId:callbackId}); + } + setInterval(function(){ + s.cpuUsage(function(cpu){ + io.emit('c',{f:'cpu',cpu:parseFloat(cpu)}); + }) + },2000); + childIO.on('connect', function(d){ + console.log('CHILD CONNECTION SUCCESS') + s.cx({ + f : 'init', + port : config.port + }) + }) + childIO.on('c', function (d) { + switch(d.f){ + case'sqlCallback': + if(s.queuedSqlCallbacks[d.callbackId]){ + s.queuedSqlCallbacks[d.callbackId](d.err,d.rows) + delete(s.queuedSqlCallbacks[d.callbackId]) + } + break; + case'init_success': + s.connected=true; + s.other_helpers=d.child_helpers; + break; + case'kill': + s.init(0,d.d); + s.kill(s.group[d.d.ke].mon[d.d.id].spawn,d.d) + break; + case'sync': + s.init(0,d.sync); + Object.keys(d.sync).forEach(function(v){ + s.group[d.sync.ke].mon[d.sync.mid][v]=d.sync[v]; + }); + break; + case'delete'://delete video + s.file('delete',s.dir.videos+d.ke+'/'+d.mid+'/'+d.file) + break; + case'insertCompleted'://close video + s.video('insertCompleted',d.d,d.k) + break; + case'cameraStop'://start camera + s.camera('stop',d.d) + break; + case'cameraStart'://start or record camera + s.camera(d.mode,d.d) + break; + } + }) + childIO.on('disconnect',function(d){ + s.connected = false; + }) +} +if(config.childNodes.mode === 'child'){ + //child node - startup functions +// fs.readdir(s.dir.videos, function(err,groupKeys) { +// groupKeys.forEach(function(groupKey){ +// fs.readdir(s.dir.videos+groupKey, function(err,monitorIds) { +// monitorIds.forEach(function(monitorId){ +// fs.readdir(s.dir.videos+groupKey+'/'+monitorId, function(err,files) { +// files.forEach(function(file){ +// if(/T[0-9][0-9]-[0-9][0-9]-[0-9][0-9]./.test(file)){ +// var filePath = s.dir.videos+groupKey+'/'+monitorId+'/'+file +// var stat = fs.statSync(filePath) +// var filesize = stat.size +// var filesizeMB = parseFloat((filesize/1000000).toFixed(2)) +// var startTime = s.nameToTime(file) +// var endTime = s.formattedTime(stat.mtime,'YYYY-MM-DD HH:mm:ss') +// fs.createReadStream(filePath) +// .on('data',function(data){ +// s.cx({ +// f:'created_file_chunk', +// mid:monitorId, +// ke:groupKey, +// chunk:data, +// filename:file, +// filesize:filesize, +// time:s.timeObject(startTime).format(), +// end:s.timeObject(endTime).format() +// }) +// }) +// .on('close',function(){ +// s.cx({ +// f:'created_file', +// mid:monitorId, +// ke:groupKey, +// filename:file, +// filesize:filesize, +// time:s.timeObject(startTime).format(), +// end:s.timeObject(endTime).format() +// }) +// }) +// .on('error',function(){ +// console.log('File Read Error',file) +// }); +// }else{ +// console.log('Not Video',file) +// } +// }) +// }) +// }) +// }) +// }) +// }) +}else{ + //master node - startup functions + setInterval(function(){ + s.cpuUsage(function(cpu){ + s.ramUsage(function(ram){ + s.tx({f:'os',cpu:cpu,ram:ram},'CPU'); + }) + }) + },10000); + setTimeout(function(){ + //get current disk used for each isolated account (admin user) on startup + s.sqlQuery('SELECT * FROM Users WHERE details NOT LIKE ?',['%"sub"%'],function(err,r){ + if(r&&r[0]){ + var count = r.length + var countFinished = 0 + r.forEach(function(v,n){ + v.size=0; + v.limit=JSON.parse(v.details).size + s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND status!=?',[v.ke,0],function(err,rr){ + ++countFinished + if(r&&r[0]){ + rr.forEach(function(b){ + v.size+=b.size + }) + } + s.systemLog(v.mail+' : '+lang.startUpText0+' : '+rr.length,v.size) + s.init('group',v) + s.systemLog(v.mail+' : '+lang.startUpText1,countFinished+'/'+count) + if(countFinished===count){ + s.systemLog(lang.startUpText4) + //preliminary monitor start + s.sqlQuery('SELECT * FROM Monitors', function(err,r) { + if(err){s.systemLog(err)} + if(r&&r[0]){ + r.forEach(function(v){ + s.init(0,v); + r.ar={}; + r.ar.id=v.mid; + Object.keys(v).forEach(function(b){ + r.ar[b]=v[b]; + }) + if(!s.group[v.ke]){ + s.group[v.ke]={} + s.group[v.ke].mon_conf={} + } + v.details=JSON.parse(v.details); + s.group[v.ke].mon_conf[v.mid]=v; + s.camera(v.mode,r.ar); + }); + } + s.processReady() + }); + } + }) + }) + }else{ + s.processReady() + } + }) + },1500) +} \ No newline at end of file diff --git a/conf.sample.json b/conf.sample.json new file mode 100644 index 0000000..e24865c --- /dev/null +++ b/conf.sample.json @@ -0,0 +1,28 @@ +{ + "port": 8080, + "addStorage": [ + {"name":"second","path":"__DIR__/videos2"} + ], + "db": { + "host": "127.0.0.1", + "user": "majesticflame", + "password": "", + "database": "ccio", + "port":3306 + }, + "mail":{ + "service": "gmail", + "auth": { + "user": "your_email@gmail.com", + "pass": "your_password_or_app_specific_password" + } + }, + "cron":{ + "key":"change_this_to_something_very_random__just_anything_other_than_this" + }, + "pluginKeys":{ + "Motion":"change_this_to_something_very_random____make_sure_to_match__/plugins/motion/conf.json", + "OpenCV":"change_this_to_something_very_random____make_sure_to_match__/plugins/opencv/conf.json", + "OpenALPR":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi" + } +} \ No newline at end of file diff --git a/cron.js b/cron.js new file mode 100644 index 0000000..ea98d8a --- /dev/null +++ b/cron.js @@ -0,0 +1,518 @@ +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +var fs = require('fs'); +var path = require('path'); +var knex = require('knex'); +var moment = require('moment'); +var exec = require('child_process').exec; +var spawn = require('child_process').spawn; +var config=require('./conf.json'); + +//set option defaults +s={ + utcOffset : moment().utcOffset() +}; +if(config.cron===undefined)config.cron={}; +if(config.cron.deleteOld===undefined)config.cron.deleteOld=true; +if(config.cron.deleteOrphans===undefined)config.cron.deleteOrphans=false; +if(config.cron.deleteNoVideo===undefined)config.cron.deleteNoVideo=true; +if(config.cron.deleteNoVideoRecursion===undefined)config.cron.deleteNoVideoRecursion=false; +if(config.cron.deleteOverMax===undefined)config.cron.deleteOverMax=true; +if(config.cron.deleteLogs===undefined)config.cron.deleteLogs=true; +if(config.cron.deleteEvents===undefined)config.cron.deleteEvents=true; +if(config.cron.deleteFileBins===undefined)config.cron.deleteFileBins=true; +if(config.cron.interval===undefined)config.cron.interval=1; +if(config.databaseType===undefined){config.databaseType='mysql'} +if(config.databaseLogs===undefined){config.databaseLogs=false} +if(config.useUTC===undefined){config.useUTC=false} + +if(!config.ip||config.ip===''||config.ip.indexOf('0.0.0.0')>-1)config.ip='localhost'; +if(!config.videosDir)config.videosDir=__dirname+'/videos/'; +if(!config.binDir){config.binDir=__dirname+'/fileBin/'} +if(!config.addStorage){config.addStorage=[]} + +// Database Connection +var databaseOptions = { + client: config.databaseType, + connection: config.db, +} +if(databaseOptions.client.indexOf('sqlite')>-1){ + databaseOptions.client = 'sqlite3'; + databaseOptions.useNullAsDefault = true; +} +if(databaseOptions.client === 'sqlite3' && databaseOptions.connection.filename === undefined){ + databaseOptions.connection.filename = __dirname+"/shinobi.sqlite" +} +s.databaseEngine = knex(databaseOptions) +s.sqlDate = function(value){ + var dateQueryFunction = '' + if(databaseOptions.client === 'sqlite3'){ + value = value.toLowerCase() + if (value.slice(-1) !== 's') { + value = value+'s' + } + dateQueryFunction = "datetime('now', '-"+value+"')" + }else{ + value = value.toUpperCase() + if (value.slice(-1) === 'S') { + value = value.slice(0, -1); + } + dateQueryFunction = "DATE_SUB(NOW(), INTERVAL "+value+")" + } + return dateQueryFunction +} +s.sqlQuery = function(query,values,onMoveOn,hideLog){ + if(!values){values=[]} + var valuesNotFunction = true; + if(typeof values === 'function'){ + var onMoveOn = values; + var values = []; + valuesNotFunction = false; + } + if(!onMoveOn){onMoveOn=function(){}} + if(values&&valuesNotFunction){ + var splitQuery = query.split('?') + var newQuery = '' + splitQuery.forEach(function(v,n){ + newQuery += v + if(values[n]){ + if(isNaN(values[n])){ + newQuery += "'"+values[n]+"'" + }else{ + newQuery += values[n] + } + } + }) + }else{ + newQuery = query + } + return s.databaseEngine.raw(newQuery) + .asCallback(function(err,r){ + if(err&&config.databaseLogs){ + s.systemLog('s.sqlQuery QUERY',query) + s.systemLog('s.sqlQuery ERROR',err) + } + if(onMoveOn) + if(typeof onMoveOn === 'function'){ + switch(databaseOptions.client){ + case'sqlite3': + if(!r)r=[] + break; + default: + if(r)r=r[0] + break; + } + onMoveOn(err,r) + }else{ + console.log(onMoveOn) + } + }) +} + +//containers +s.overlapLock={}; +s.alreadyDeletedRowsWithNoVideosOnStart={}; +//functions +s.checkCorrectPathEnding=function(x){ + var length=x.length + if(x.charAt(length-1)!=='/'){ + x=x+'/' + } + return x.replace('__DIR__',__dirname) +} +s.dir={ + videos:s.checkCorrectPathEnding(config.videosDir), + fileBin:s.checkCorrectPathEnding(config.binDir), + addStorage:config.addStorage, +}; +s.moment=function(e,x){ + if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'}; + return moment(e).format(x); +} +s.utcToLocal = function(time){ + return moment.utc(time).utcOffset(s.utcOffset).format() +} +s.localToUtc = function(time){ + return moment(time).utc() +} +s.nameToTime=function(x){x=x.replace('.webm','').replace('.mp4','').split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;} +io = require('socket.io-client')('ws://'+config.ip+':'+config.port);//connect to master +s.cx=function(x){x.cronKey=config.cron.key;return io.emit('cron',x)} +//emulate master socket emitter +s.tx=function(x,y){s.cx({f:'s.tx',data:x,to:y})} +s.video=function(x,y){s.cx({f:'s.video',data:x,file:y})} +//Cron Job +s.cx({f:'init',time:moment()}) +s.getVideoDirectory=function(e){ + if(e.mid&&!e.id){e.id=e.mid}; + if(e.details&&(e.details instanceof Object)===false){ + try{e.details=JSON.parse(e.details)}catch(err){} + } + if(e.details.dir&&e.details.dir!==''){ + return s.checkCorrectPathEnding(e.details.dir)+e.ke+'/'+e.id+'/' + }else{ + return s.dir.videos+e.ke+'/'+e.id+'/'; + } +} +s.getFileBinDirectory=function(e){ + if(e.mid&&!e.id){e.id=e.mid}; + return s.dir.fileBin+e.ke+'/'+e.id+'/'; +} +//filters set by the user in their dashboard +//deleting old videos is part of the filter - config.cron.deleteOld +s.checkFilterRules=function(v,callback){ + //filters + if(!v.d.filters||v.d.filters==''){ + v.d.filters={}; + } + //delete old videos with filter + if(config.cron.deleteOld===true){ + v.d.filters.deleteOldByCron={ + "id":"deleteOldByCron", + "name":"deleteOldByCron", + "sort_by":"time", + "sort_by_direction":"ASC", + "limit":"", + "enabled":"1", + "archive":"0", + "email":"0", + "delete":"1", + "execute":"", + "where":[{ + "p1":"end", + "p2":"<", + "p3":s.sqlDate(v.d.days+" DAYS"), + "p3_type":"function", + }] + }; + } + var keys = Object.keys(v.d.filters) + if(keys.length>0){ + keys.forEach(function(m,current){ + var b=v.d.filters[m]; + if(b.enabled==="1"){ + b.ar=[v.ke]; + b.sql=[]; + b.where.forEach(function(j,k){ + if(j.p1==='ke'){j.p3=v.ke} + switch(j.p3_type){ + case'function': + b.sql.push(j.p1+' '+j.p2+' '+j.p3) + break; + default: + b.sql.push(j.p1+' '+j.p2+' ?') + b.ar.push(j.p3) + break; + } + }) + b.sql='WHERE ke=? AND status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND ('+b.sql.join(' AND ')+')'; + if(b.sort_by&&b.sort_by!==''){ + b.sql+=' ORDER BY `'+b.sort_by+'` '+b.sort_by_direction + } + if(b.limit&&b.limit!==''){ + b.sql+=' LIMIT '+b.limit + } + s.sqlQuery('SELECT * FROM Videos '+b.sql,b.ar,function(err,r){ + if(r&&r[0]){ + b.cx={ + f:'filters', + name:b.name, + videos:r, + time:moment(), + ke:v.ke, + id:b.id + }; + if(b.archive==="1"){ + s.cx({f:'filters',ff:'archive',videos:r,time:moment(),ke:v.ke,id:b.id}); + }else{ + if(b.delete==="1"){ + s.cx({f:'filters',ff:'delete',videos:r,time:moment(),ke:v.ke,id:b.id}); + } + } + if(b.email==="1"){ + b.cx.ff='email'; + b.cx.delete=b.delete; + b.cx.mail=v.mail; + b.cx.execute=b.execute; + b.cx.query=b.sql; + s.cx(b.cx); + } + if(b.execute&&b.execute!==""){ + s.cx({f:'filters',ff:'execute',execute:b.execute,time:moment()}); + } + } + }) + + } + if(current===keys.length-1){ + //last filter + callback() + } + }) + }else{ + //no filters + callback() + } +} +//database rows with no videos in the filesystem +s.deleteRowsWithNoVideo=function(v,callback){ + if( + config.cron.deleteNoVideo===true&&( + config.cron.deleteNoVideoRecursion===true|| + (config.cron.deleteNoVideoRecursion===false&&!s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]) + ) + ){ + s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]=true; + es={}; + s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND status!=0 AND details NOT LIKE \'%"archived":"1"%\' AND time < '+s.sqlDate('10 MINUTE'),[v.ke],function(err,evs){ + if(evs&&evs[0]){ + es.del=[];es.ar=[v.ke]; + evs.forEach(function(ev){ + var details = JSON.parse(ev.details) + var filename = ev.time + var dir = s.getVideoDirectory(ev)+s.moment(filename)+'.'+ev.ext; + var fileExists = fs.existsSync(dir) + if(details.isUTC === true){ + filename = s.localToUtc(filename).format('YYYY-MM-DDTHH-mm-ss') + dir = s.getVideoDirectory(ev)+filename+'.'+ev.ext; + fileExists = fs.existsSync(dir) + } + if(fileExists !== true){ + s.video('delete',ev) + s.tx({f:'video_delete',filename:filename+'.'+ev.ext,mid:ev.mid,ke:ev.ke,time:ev.time,end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+ev.ke); + } + }); + if(es.del.length>0){ + s.cx({f:'deleteNoVideo',msg:es.del.length+' SQL rows with no file deleted',ke:v.ke,time:moment()}) + } + } + setTimeout(function(){ + callback() + },3000) + }) + }else{ + callback() + } +} +//info about what the application is doing +s.deleteOldLogs=function(v,callback){ + if(!v.d.log_days||v.d.log_days==''){v.d.log_days=10}else{v.d.log_days=parseFloat(v.d.log_days)}; + if(config.cron.deleteLogs===true&&v.d.log_days!==0){ + s.sqlQuery("DELETE FROM Logs WHERE ke=? AND `time` < "+s.sqlDate('? DAYS'),[v.ke,v.d.log_days],function(err,rrr){ + callback() + if(err)return console.error(err); + if(rrr.affectedRows && rrr.affectedRows.length>0){ + s.cx({f:'deleteLogs',msg:rrr.affectedRows+' SQL rows older than '+v.d.log_days+' days deleted',ke:v.ke,time:moment()}) + } + }) + }else{ + callback() + } +} +//events - motion, object, etc. detections +s.deleteOldEvents=function(v,callback){ + if(!v.d.event_days||v.d.event_days==''){v.d.event_days=10}else{v.d.event_days=parseFloat(v.d.event_days)}; + if(config.cron.deleteEvents===true&&v.d.event_days!==0){ + s.sqlQuery("DELETE FROM Events WHERE ke=? AND `time` < "+s.sqlDate('? DAYS'),[v.ke,v.d.event_days],function(err,rrr){ + callback() + if(err)return console.error(err); + if(rrr.affectedRows && rrr.affectedRows.length>0){ + s.cx({f:'deleteEvents',msg:rrr.affectedRows+' SQL rows older than '+v.d.event_days+' days deleted',ke:v.ke,time:moment()}) + } + }) + }else{ + callback() + } +} +//check for temporary files (special archive) +s.deleteOldFileBins=function(v,callback){ + if(!v.d.fileBin_days||v.d.fileBin_days==''){v.d.fileBin_days=10}else{v.d.fileBin_days=parseFloat(v.d.fileBin_days)}; + if(config.cron.deleteFileBins===true&&v.d.fileBin_days!==0){ + var fileBinQuery = " FROM Files WHERE ke=? AND `date` < "+s.sqlDate('? DAYS'); + s.sqlQuery("SELECT *"+fileBinQuery,[v.ke,v.d.fileBin_days],function(err,files){ + if(files&&files[0]){ + //delete the files + files.forEach(function(file){ + fs.unlink(s.getFileBinDirectory(file)+file.name,function(err){ +// if(err)console.error(err) + }) + }) + //delete the database rows + s.sqlQuery("DELETE"+fileBinQuery,[v.ke,v.d.fileBin_days],function(err,rrr){ + callback() + if(err)return console.error(err); + if(rrr.affectedRows && rrr.affectedRows.length>0){ + s.cx({f:'deleteFileBins',msg:rrr.affectedRows+' files older than '+v.d.fileBin_days+' days deleted',ke:v.ke,time:moment()}) + } + }) + }else{ + callback() + } + }) + }else{ + callback() + } +} +//check for files with no database row +s.checkForOrphanedFiles=function(v,callback){ + if(config.cron.deleteOrphans===true){ + var finish=function(count){ + if(count>0){ + s.cx({f:'deleteOrphanedFiles',msg:count+' SQL rows with no database row deleted',ke:v.ke,time:moment()}) + } + callback() + } + e={}; + var numberOfItems = 0; + s.sqlQuery('SELECT * FROM Monitors WHERE ke=?',[v.ke],function(arr,b) { + if(b&&b[0]){ + b.forEach(function(mon,m){ + fs.readdir(s.getVideoDirectory(mon), function(err, items) { + e.query=[]; + e.filesFound=[mon.ke,mon.mid]; + numberOfItems+=items.length; + if(items&&items.length>0){ + items.forEach(function(v,n){ + e.query.push('time=?') + e.filesFound.push(s.nameToTime(v)) + }) + s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND mid=? AND ('+e.query.join(' OR ')+')',e.filesFound,function(arr,r) { + if(!r){r=[]}; + e.foundSQLrows=[]; + r.forEach(function(v,n){ + v.index=e.filesFound.indexOf(s.moment(v.time,'YYYY-MM-DD HH:mm:ss')); + if(v.index>-1){ + delete(items[v.index-2]); + } + }); + items.forEach(function(v,n){ + if(v&&v!==null){ + exec('rm '+s.getVideoDirectory(mon)+v); + } + if(m===b.length-1&&n===items.length-1){ + finish(numberOfItems) + } + }) + }) + }else{ + if(m===b.length-1){ + finish(numberOfItems) + } + } + }) + }); + }else{ + finish(numberOfItems) + } + }); + }else{ + callback() + } +} +//user processing function +s.processUser = function(number,rows){ + var v = rows[number]; + if(!v){ + //no user object given + return + } + console.log(v) + if(!s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]){ + s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]=false; + } + if(!s.overlapLock[v.ke]){ + // set overlap lock + s.overlapLock[v.ke]=true; + //set permissions + v.d=JSON.parse(v.details); + //size + if(!v.d.size||v.d.size==''){v.d.size=10000}else{v.d.size=parseFloat(v.d.size)}; + //days to keep videos + if(!v.d.days||v.d.days==''){v.d.days=5}else{v.d.days=parseFloat(v.d.days)}; + s.sqlQuery('SELECT * FROM Monitors WHERE ke=?', [v.ke], function(err,rr) { + if(!v.d.filters||v.d.filters==''){ + v.d.filters={}; + } + rr.forEach(function(b,m){ + b.details=JSON.parse(b.details); + if(b.details.max_keep_days&&b.details.max_keep_days!==''){ + v.d.filters['deleteOldByCron'+b.mid]={ + "id":'deleteOldByCron'+b.mid, + "name":'deleteOldByCron'+b.mid, + "sort_by":"time", + "sort_by_direction":"ASC", + "limit":"", + "enabled":"1", + "archive":"0", + "email":"0", + "delete":"1", + "execute":"", + "where":[{ + "p1":"ke", + "p2":"=", + "p3":b.mid + },{ + "p1":"end", + "p2":"<", + "p3":s.sqlDate(b.details.max_keep_days+" DAYS"), + "p3_type":"function", + }] + }; + } + }) + s.deleteOldLogs(v,function(){ + console.log('deleteOldLogs') + s.deleteOldFileBins(v,function(){ + console.log('deleteOldFileBins') + s.deleteOldEvents(v,function(){ + console.log('deleteOldEvents') + s.checkFilterRules(v,function(){ + console.log('checkFilterRules') + s.deleteRowsWithNoVideo(v,function(){ + console.log('deleteRowsWithNoVideo') + s.checkForOrphanedFiles(v,function(){ + //done user, unlock current, and do next + s.overlapLock[v.ke]=false; + s.processUser(number+1,rows) + }) + }) + }) + }) + }) + }) + }) + }else{ + s.processUser(number+1,rows) + } +} +//recursive function +s.cron=function(){ + x={}; + s.cx({f:'start',time:moment()}) + s.sqlQuery('SELECT ke,uid,details,mail FROM Users WHERE details NOT LIKE \'%"sub"%\'', function(err,rows) { + if(err){ + console.error(err) + } + if(rows&&rows[0]){ + s.processUser(0,rows) + } + }) + s.timeout=setTimeout(function(){ + s.cron(); + },parseFloat(config.cron.interval)*60000*60) +} +s.cron(); +//socket commander +io.on('f',function(d){ + switch(d.f){ + case'start':case'restart': + clearTimeout(s.timeout); + s.cron(); + break; + case'stop': + clearTimeout(s.timeout); + break; + } +}) +console.log('Shinobi : cron.js started') \ No newline at end of file diff --git a/definitions/en_CA.json b/definitions/en_CA.json new file mode 100644 index 0000000..223b35e --- /dev/null +++ b/definitions/en_CA.json @@ -0,0 +1,1192 @@ +{ + "Monitor Settings": { + "section": "Monitor Settings", + "blocks": { + "Identity": { + "name": "Identity", + "color": "", + "info": [ + { + "name": "mode", + "field": "Mode", + "description": "This is the primary task of the monitor.", + "default": "Disabled", + "example": "", + "possible": [ + { + "name": "Disabled", + "info": "Inactive monitor, no process will be created in this mode." + }, + { + "name": "Watch-Only", + "info": "Monitor will only stream, no recording will occur unless otherwise ordered by API or Detector." + }, + { + "name": "Record", + "info": "Continuous Recording. Segments are made every 15 minutes by default." + } + ] + }, + { + "name": "mid", + "field": "Monitor ID", + "description": "This is a non-changeable identifier for the monitor. You can duplicate a monitor by double clicking the Monitor ID and changing it.", + "default": "Provided by Server", + "example": "awFST99MGn", + "possible": "" + }, + { + "name": "name", + "field": "Name", + "description": "This is the human-readable display name for the monitor.", + "default": "", + "example": "Bunny", + "possible": "" + }, + { + "name": "detail=fatal_max", + "field": "Retry Connection", + "description": "The number of times to retry for network connection between the server and camera before setting the monitor to Disabled. No decimals. Set to 0 to retry forever.", + "default": "10", + "example": "100000", + "possible": "" + }, + { + "name": "detail=notes", + "field": "Notes", + "description": "Comments you want to leave for this camera.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=dir", + "field": "Storage Location", + "description": "Location of where recorded files will be saved. You can configure more locations with the addStorage variable.", + "default": "", + "example": "", + "possible": "" + } + ] + }, + "Input": { + "name": "Input", + "color": "forestgreen", + "info": [ + { + "name": "type", + "field": "Input Type", + "description": "The method that will used to consume the video stream.", + "default": "JPEG", + "example": "", + "possible": [ + { + "name": "JPEG", + "info": "Reading snapshots from a URL and making a stream and/or video from them." + }, + { + "name": "MJPEG", + "info": "Similar to JPEG except the frame handling is done by FFMPEG, not Shinobi." + }, + { + "name": "H.264", + "info": "Reading a high quality video streas that sometimes include audio." + }, + { + "name": "Local", + "info": "Reading Capture Cards, Webcams, or Integrated Cameras." + }, + { + "name": "Shinobi Streamer", + "info": "Continuous Recording. Segments are made every 15 minutes by default." + } + ] + }, + { + "name": "detail=auto_host_enable", + "field": "Automatic", + "description": "Feed the individual pieces required to build a stream URL or provide the full URL and allow Shinobi to parse it for you.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=auto_host", + "field": "Full URL Path", + "description": "The full Stream URL.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=accelerator", + "field": "Accelerator", + "description": "Hardware Acceleration (HWAccel) for decoding streams.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "protocol", + "field": "Connection Type", + "description": "The protocol that will used to consume the video stream.", + "default": "HTTP", + "example": "", + "possible": [ + { + "name": "HTTP", + "info": "Standard connection method." + }, + { + "name": "HTTPS", + "info": "Standard connection method with SSL." + }, + { + "name": "RTSP", + "info": "Real Time Streaming Protocol" + }, + { + "name": "UDP", + "info": "Near restrictionless data transfer method." + } + ] + }, + { + "name": "detail=muser", + "field": "Username", + "description": "The user login for your camera", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=mpass", + "field": "Password", + "description": "The password for your camera", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "host", + "field": "Host", + "description": "Connection address", + "default": "", + "example": "111.111.111.111", + "possible": "" + }, + { + "name": "port", + "field": "Port", + "description": "Port number that your camera is streaming out on.", + "default": "80", + "example": "554", + "possible": "1-65535" + }, + { + "name": "detail=port_force", + "field": "Force Port", + "description": "Using the default web port can allow automatic switch to other ports for streams like RTSP.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "path", + "field": "Path", + "description": "The path to your camera", + "default": "", + "example": "/video.h264", + "possible": "" + }, + { + "name": "detail=aduration", + "field": "Analyzation Duration", + "description": "Specify how many microseconds are analyzed to probe the input. Set to 100000 if you are using RTSP and having stream issues.", + "default": "", + "example": "100000", + "possible": "" + }, + { + "name": "detail=probesize", + "field": "Probe Size", + "description": "Specify how big to make the analyzation probe for the input. Set to 100000 if you are using RTSP and having stream issues.", + "default": "", + "example": "100000", + "possible": "" + }, + { + "name": "detail=rtsp_transport", + "field": "RTSP Transport", + "description": "The transport protocol your camera will use. TCP is usually the best choice.", + "default": "", + "example": "", + "possible": [ + { + "name": "Auto", + "info": "Let FFMPEG decide. Normally it will try UDP first." + }, + { + "name": "TCP", + "info": "Set it to this if UDP starts giving undesired results." + }, + { + "name": "UDP", + "info": "FFMPEG tries this first." + }, + { + "name": "HTTP", + "info": "Standard connection method." + } + ] + } + ] + }, + "Stream": { + "name": "Stream", + "color": "blue", + "info": [ + { + "name": "detail=stream_type", + "field": "Stream Type", + "description": "The method that will used to consume the video stream.", + "default": "HLS", + "example": "", + "possible": [ + { + "name": "MJPEG", + "info": "Standard Motion JPEG image. No audio." + }, + { + "name": "HLS", + "info": "Similar method to facebook live streams. Includes audio if input provides it. There is a delay of about 4-6 seconds because this method records segments then pushes them to the client rather than push as while it creates them." + }, + { + "name": "Base64", + "info": "Sending Base64 encoded frames over WebSocket. This avoids caching but there is no audio." + }, + { + "name": "FLV", + "info": "Sending FLV encoded frames over WebSocket." + }, + { + "name": "kVid", + "info": "Using Kevin Godell's custom JavaScript MP4 segmenting engine." + } + ] + }, + { + "name": "detail=signal_check", + "field": "Check Signal Interval", + "description": "How often your client will check each stream to see if it is alive. This is calculated in minutes.", + "default": "10", + "example": "", + "possible": "" + }, + { + "name": "detail=stream_flv_type", + "field": "FLV Stream Type", + "description": "The method you will view your FLV stream. Both methods are always active for each stream regardless of your viewing choice for the Shinobi Dashboard.", + "default": "10", + "example": "", + "possible": "" + }, + { + "name": "detail=signal_check_log", + "field": "Log Signal Event", + "description": "This is for the client side only. It will display in the log thread when client side signal checks occur.", + "default": "No", + "example": "", + "possible": [ + { + "name": "No", + "info": "No signal check." + }, + { + "name": "Yes", + "info": "Check signal based on the number of minutes provided." + } + ] + }, + { + "name": "detail=stream_quality", + "field": "Quality", + "description": "Low number means higher quality. Higher number means less quality.", + "default": "15", + "example": "1", + "possible": "1-23" + }, + { + "name": "detail=stream_fps", + "field": "Rate (FPS)", + "description": "The speed in which frames are displayed to clients, in Frames Per Second. Be aware there is no default. This can lead to high bandwidth usage.", + "default": "", + "example": "1", + "possible": "" + }, + { + "name": "height", + "field": "Height", + "description": "Height of the stream image.", + "default": "640", + "example": "1280", + "possible": "" + }, + { + "name": "width", + "field": "Width", + "description": "Width of the stream image.", + "default": "480", + "example": "720", + "possible": "" + }, + { + "name": "detail=svf", + "field": "Video Filter", + "description": "Place FFMPEG video filters in this box to affect the streaming portion. No spaces.", + "default": "", + "example": "", + "possible": "" + } + ] + }, + "Stream - HLS": { + "name": "Stream - HLS", + "color": "blue", + "info": [ + { + "name": "detail=stream_vcodec", + "field": "Video Codec", + "description": "Video codec for streaming.", + "default": "copy", + "example": "", + "possible": [ + { + "name": "Default", + "info": "Let Shinobi choose." + }, + { + "name": "Auto", + "info": "Let FFMPEG choose." + }, + { + "name": "libvpx", + "info": "Used for WebM video." + }, + { + "name": "libvpx-vp9", + "info": "Used for WebM video." + }, + { + "name": "libx264", + "info": "Used for MP4 video." + }, + { + "name": "libx265", + "info": "Used for MP4 video." + }, + { + "name": "copy", + "info": "Used for MP4 video. Has very low CPU usage but cannot use video filters and filesizes may be gigantic. Best to setup your MP4 settings camera-side when using this option." + } + ] + }, + { + "name": "detail=stream_acodec", + "field": "Audio Codec", + "description": "Audio codec for streaming.", + "default": "No Audio", + "example": "", + "possible": [ + { + "name": "Default", + "info": "Let Shinobi choose." + }, + { + "name": "Auto", + "info": "Let FFMPEG choose." + }, + { + "name": "No Audio", + "info": "No Audio, this is an option that must be set in some parts of the world due to legal reasons." + }, + { + "name": "libvorbis", + "info": "Used for WebM video." + }, + { + "name": "libopus", + "info": "Used for WebM video." + }, + { + "name": "libmp3lame", + "info": "Used for MP4 video." + }, + { + "name": "aac", + "info": "Used for MP4 video." + }, + { + "name": "ac3", + "info": "Used for MP4 video." + }, + { + "name": "copy", + "info": "Used for MP4 video. Has very low CPU usage but some audio codecs need custom flags like -strict 2 for aac." + } + ] + }, + { + "name": "detail=hls_time", + "field": "HLS Segment Length", + "description": "How long each video segment should be, in minutes. Each segment will be drawn by the client through an m3u8 file. Shorter segments take less space.", + "default": "2", + "example": "3", + "possible": "" + }, + { + "name": "detail=hls_list_size", + "field": "HLS List Size", + "description": "The number of segments maximum before deleting old segments automatically.", + "default": "2", + "example": "3", + "possible": "" + }, + { + "name": "detail=preset_stream", + "field": "HLS Preset", + "description": "Preset flag for certain video encoders. If you find your camera is crashing every few seconds : try leaving it blank.", + "default": "", + "example": "ultrafast", + "possible": "" + }, + { + "name": "detail=stream_scale_x", + "field": "Width", + "description": "Width of the stream image.", + "default": "640", + "example": "640", + "possible": "" + }, + { + "name": "detail=stream_scale_y", + "field": "Height", + "description": "Height of the stream image.", + "default": "480", + "example": "480", + "possible": "" + }, + { + "name": "detail=tv_channel", + "field": "TV Channel", + "description": "This monitor will have TV Channel features enabled. You will be able to view it in your TV Channel list.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=tv_channel_id", + "field": "TV Channel ID", + "description": "A Custom ID for the Channel.", + "default": "", + "example": "", + "possible": "" + } + ] + }, + "Recording": { + "name": "Recording", + "color": "red", + "info": [ + { + "name": "ext", + "field": "Record File Type", + "description": "The file type for your recorded video file.", + "default": "MP4", + "example": "", + "possible": [ + { + "name": "MP4", + "info": "This file type is playable is almost all modern web browsers, that includes mobile. The filesize just tends to be larger unless you lower the quality." + }, + { + "name": "WebM", + "info": "Small filesize, low client compatibility. Good for uploading to sites like YouTube." + } + ] + }, + { + "name": "detail=vcodec", + "field": "Video Codec", + "description": "Video codec for recording.", + "default": "copy", + "example": "", + "possible": [ + { + "name": "Default", + "info": "Let Shinobi choose." + }, + { + "name": "Auto", + "info": "Let FFMPEG choose." + }, + { + "name": "libvpx", + "info": "Used for WebM video." + }, + { + "name": "libvpx-vp9", + "info": "Used for WebM video." + }, + { + "name": "libx264", + "info": "Used for MP4 video." + }, + { + "name": "libx265", + "info": "Used for MP4 video." + }, + { + "name": "copy", + "info": "Used for MP4 video. Has very low CPU usage but cannot use video filters and filesizes may be gigantic. Best to setup your MP4 settings camera-side when using this option." + } + ] + }, + { + "name": "detail=acodec", + "field": "Audio Codec", + "description": "Audio codec for recording.", + "default": "No Audio", + "example": "", + "possible": [ + { + "name": "Default", + "info": "Let Shinobi choose." + }, + { + "name": "Auto", + "info": "Let FFMPEG choose." + }, + { + "name": "No Audio", + "info": "No Audio, this is an option that must be set in some parts of the world due to legal reasons." + }, + { + "name": "libvorbis", + "info": "Used for WebM video." + }, + { + "name": "libopus", + "info": "Used for WebM video." + }, + { + "name": "libmp3lame", + "info": "Used for MP4 video." + }, + { + "name": "aac", + "info": "Used for MP4 video." + }, + { + "name": "ac3", + "info": "Used for MP4 video." + }, + { + "name": "copy", + "info": "Used for MP4 video. Has very low CPU usage but some audio codecs need custom flags like -strict 2 for aac." + } + ] + }, + { + "name": "crf", + "field": "Quality", + "description": "Low number means higher quality. Higher number means less quality.", + "default": "15", + "example": "1", + "possible": "1-23" + }, + { + "name": "preset_record", + "field": "Preset", + "description": "Preset flag for certain video encoders. If you find your camera is crashing every few seconds : try leaving it blank.", + "default": "", + "example": "ultrafast", + "possible": "" + }, + { + "name": "fps", + "field": "Video Record Rate (FPS)", + "description": "The speed in which frames are recorded to files, Frames Per Second. Be aware there is no default. This can lead to large files. Best to set this camera-side.", + "default": "", + "example": "2", + "possible": "" + }, + { + "name": "height", + "field": "Record Height", + "description": "Height of the stream image.", + "default": "640", + "example": "1280", + "possible": "" + }, + { + "name": "width", + "field": "Record Width", + "description": "Width of the stream image.", + "default": "480", + "example": "720", + "possible": "" + }, + { + "name": "detail=cutoff", + "field": "Recording Segment Interval", + "description": "In minutes. When to slice off and start a new video file.", + "default": "15", + "example": "60", + "possible": "" + }, + { + "name": "detail=dqf", + "field": "Double Quote Directory", + "description": "Some directories have spaces depending on how you setup your OS.", + "default": "No", + "example": "", + "possible": [ + { + "name": "No", + "info": "No is the default." + }, + { + "name": "Yes", + "info": "Using this may crash some cameras." + } + ] + }, + { + "name": "detail=vf", + "field": "Record Video Filter", + "description": "Place FFMPEG video filters in this box to affect the recording portion. No spaces.", + "default": "", + "example": "", + "possible": "" + } + ] + }, + "Timestamp": { + "name": "Timestamp", + "color": "red", + "info": [ + { + "name": "detail=timestamp_font", + "field": "Font Path", + "description": "Font File to style your timestamp.", + "default": "/usr/share/fonts/truetype/freefont/FreeSans.ttf", + "example": "", + "possible": "" + }, + { + "name": "detail=timestamp_font_size", + "field": "Font Size", + "description": "Font size in pt.", + "default": "10", + "example": "", + "possible": "" + }, + { + "name": "detail=timestamp_color", + "field": "Text Color", + "description": "Timstamp text color.", + "default": "white", + "example": "", + "possible": "" + }, + { + "name": "detail=timestamp_box_color", + "field": "Text Box Color", + "description": "Timstamp backdrop color.", + "default": "0x00000000@1", + "example": "", + "possible": "" + }, + { + "name": "detail=timestamp_x", + "field": "Position X", + "description": "Horiztonal Position of Timestamp", + "default": "(w-tw)/2", + "example": "", + "possible": "" + }, + { + "name": "detail=timestamp_y", + "field": "Position Y", + "description": "Vertical Position of Timestamp", + "default": "0", + "example": "", + "possible": "" + } + ] + }, + "Detector": { + "name": "Detector", + "color": "orange", + "info": [ + { + "name": "detail=detector", + "field": "Enabled", + "description": "This will add another output in the FFMPEG command for the motion detector. A detector plugin must be connected for this to have any effect.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_pam", + "field": "Use Built-In", + "description": "Use Kevin Godell's Motion Detector. This is built into Shinobi and requires no other configuration to activate.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_trigger", + "field": "Trigger Record", + "description": "This will order the camera to record if it is set to \"Watch-Only\" when a motion even is detected.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_timeout", + "field": "Recording Timeout", + "description": "The length of time \"Trigger Record\" will run for. This is read in minutes.", + "default": "10", + "example": "", + "possible": "" + }, + { + "name": "detail=watchdog_reset", + "field": "Timeout Reset on Next Event", + "description": "If there is an overlap in trigger record should it reset.", + "default": "No", + "example": "1", + "possible": [ + { + "name": "No", + "info": "Finish the current 10 minute order.." + }, + { + "name": "Yes", + "info": "Reset the timer" + } + ] + }, + { + "name": "detail=detector_save", + "field": "Save Events to SQL", + "description": "Save Motion Events in SQL. This will allow display of motion over video during the time motion events occured in the Power Viewer.", + "default": "Yes", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_send_frames", + "field": "Send Frames", + "description": "Push frames to the connected plugin to be analyzed.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_frame_save", + "field": "Save Frames to Events", + "description": "Save frames to the event row in the database as a base64 string. Enabling this can drain performance.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_mail", + "field": "Email on Trigger", + "description": "Recieve an email of an image during a motion event to the master account for the camera group. You must setup SMTP details in conf.json.", + "default": "No", + "example": "1", + "possible": [ + { + "name": "No", + "info": "Finish the current 10 minute order." + }, + { + "name": "Yes", + "info": "Reset the timer" + } + ] + }, + { + "name": "detail=detector_mail_timeout", + "field": "Allow Next Email", + "description": "The amount of time until a trigger is allowed to send another email with motion details and another image.", + "default": "10", + "example": "0.5", + "possible": "" + }, + { + "name": "detail=detector_fps", + "field": "Detector Rate (FPS)", + "description": "How many frames a second to send to the motion detector; 1 is the default.", + "default": "1", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_scale_x", + "field": "Feed-in Image Width", + "description": "Width of the image being detected. Smaller sizes take less CPU.", + "default": "", + "example": "640", + "possible": "" + }, + { + "name": "detail=detector_scale_y", + "field": "Feed-in Image Height", + "description": "Height of the image being detected. Smaller sizes take less CPU.", + "default": "", + "example": "480", + "possible": "" + }, + { + "name": "detail=detector_frame", + "field": "Full Frame Detection", + "description": "This will read the entire frame for pixel differences.", + "default": "Yes", + "example": "", + "possible": [ + { + "name": "No", + "info": "Makes motion detector do nothing if regions are not specified. Which is a stupid option to have if motion detection is on. One day we will remove this option." + }, + { + "name": "Yes", + "info": "Read entire frame." + } + ] + }, + { + "name": "detail=detector_sensitivity", + "field": "Indifference", + "description": "How much Shinobi doesn't care about motion before doing something. The opposite of sensitivity; a lower number means it will trigger sooner. The value ranges up to 15(+) decimal places. 10 is default, 0.005 is pretty sensitive to motion changes. Note: If using Region Editor, leave this blank, and set indifference in the Region Editor (below).", + "default": "10", + "example": "10", + "possible": "" + }, + { + "name": "detail=detector_webhook", + "field": "Webhook", + "description": "Send a GET request to a URL with some values from the event.", + "default":"No", + "example": "", + "possible":"" + }, + { + "name": "detail=detector_command_enable", + "field": "Detector Command", + "description": "You may use this to trigger a script on command.", + "default": "No", + "example": "", + "possible": [ + { + "name": "No", + "info": "No script will run." + }, + { + "name": "Yes", + "info": "Trigger the script that is set in the Command option. Command is only visible when selecting this option." + } + ] + }, + { + "name": "detail=detector_command", + "field": "Command", + "description": "The command that will run. This is the equivalent of running a shell command from terminal.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_command_timeout", + "field": "Allow Next Command", + "description": "This value is a timer to allow the next running of your script. This value is in minutes.", + "default": "10", + "example": "0.1", + "possible": "Any number." + } + ] + }, + "\"No Motion\" Detector": { + "name": "\"No Motion\" Detector", + "color": "orange", + "info": [ + { + "name": "detail=detector_notrigger_mail", + "field": "Email on \"No Motion\"", + "description": "If motion has not been detected after the timeout period you will recieve an email.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=detector_notrigger_timeout", + "field": "Timeout", + "description": "Timeout is calculated in minutes.", + "default": "1", + "example": "", + "possible": "" + } + ] + }, + "Custom": { + "name": "Custom", + "color": "navy", + "info": [ + { + "name": "detail=cust_input", + "field": "Input Flags", + "description": "Custom Flags that bind to the Input of the FFMPEG process.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=cust_snap", + "field": "Snapshot Flags", + "description": "Custom Flags that bind to the Snapshots.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=cust_detect", + "field": "Detector Flags", + "description": "Custom Flags that bind to the stream Detector uses for analyzation.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=cust_stream", + "field": "Stream Flags", + "description": "Custom Flags that bind to the Stream (client side view) of the FFMPEG process.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=cust_record", + "field": "Recording Flags", + "description": "Custom Flags that bind to the recording of the FFMPEG process.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=custom_output", + "field": "Output Method", + "description": "Add a custom output like JPEG frames or send data straight to another server.", + "default": "", + "example": "", + "possible": "" + } + ] + }, + "Logging": { + "name": "Logging", + "color": "green", + "info": [ + { + "name": "detail=loglevel", + "field": "Log Level", + "description": "The amount of data to provide while doing the job.", + "default": "No", + "example": "", + "possible": [ + { + "name": "Silent", + "info": "None. This will silence all logging." + }, + { + "name": "Fatal", + "info": "Display only fatal errors." + }, + { + "name": "On Error", + "info": "Display all important errors. Note : this doesn't always show important information." + }, + { + "name": "All Warnings", + "info": "Display all warnings. Use this if you can't find out what's wrong with your camera." + }, + { + "name": "Debug", + "info": "Show all information FFMPEG can provide on STDERR while doing the job." + } + ] + }, + { + "name": "detail=sqllog", + "field": "Save Log in SQL", + "description": "Use this with caution as FFMPEG likes to throw up superfluous data at times which can lead to a lot of database rows.", + "default": "No", + "example": "", + "possible": [ + { + "name": "No", + "info": "No is the default." + }, + { + "name": "Yes", + "info": "Do this if you are having recurring issues only." + } + ] + } + ] + } + } + }, + "Account Settings": { + "section": "Account Settings", + "blocks": { + "Profile": { + "name": "Profile", + "color": "grey", + "info": [ + { + "name": "mail", + "field": "Email", + "description": "The login for accounts. The main account holder's email address will get notifications.", + "default": "", + "example": "ccio@m03.ca", + "possible": "Email compliant string." + }, + { + "name": "pass", + "field": "Password", + "description": "Leave blank to keep the same password during settings modification.", + "default": "", + "example": "ccio@m03.ca", + "possible": "" + }, + { + "name": "detail=size", + "field": "Max Storage Amount", + "description": "The amount max space Shinobi will allow to be consumed before purging. This value is read in megabytes.", + "default": "10000", + "example": "600000", + "possible": "Up to 95% of your maximum storage space if only one master account exists." + }, + { + "name": "detail=days", + "field": "Number of Days to keep Videos", + "description": "The number of days to keep videos before purging.", + "default": "7", + "example": "30", + "possible": "" + }, + { + "name": "detail=event_days", + "field": "Number of Days to keep Events", + "description": "The number of days to keep events before purging.", + "default": "7", + "example": "30", + "possible": "" + }, + { + "name": "detail=log_days", + "field": "Number of Days to keep Logs", + "description": "The number of days to keep logs before purging.", + "default": "7", + "example": "30", + "possible": "" + } + ] + }, + "Monitor Groups": { + "name": "Monitor Groups", + "color": "blue", + "info": [ + { + "field": "Groups", + "description": "The list of groups you have created.", + "default": "", + "example": "", + "possible": "" + }, + { + "field": "Group Name", + "description": "Name of selected group.", + "default": "", + "example": "", + "possible": "" + } + ] + }, + "WebDAV": { + "name": "WebDAV", + "color": "forestgreen", + "info": [ + { + "name": "detail=webdav_url", + "field": "URL", + "description": "The connection URL for your WebDAV server.", + "default": "", + "example": "http://owncloud.server/remote.php/webdav/", + "possible": "" + }, + { + "name": "detail=webdav_user", + "field": "Username", + "description": "The username required to access this server.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=webdav_pass", + "field": "Password", + "description": "The password required to access this server.", + "default": "", + "example": "", + "possible": "" + }, + { + "name": "detail=webdav_save", + "field": "Autosave", + "description": "Whether or not the server should auto upload videos as they are finished.", + "default": "No", + "example": "", + "possible": "" + }, + { + "name": "detail=webdav_dir", + "field": "Save Directory", + "description": "The directory where videos will be saved.", + "default": "/", + "example": "/videos", + "possible": "" + } + ] + }, + "Custom Styles": { + "name": "Custom Styles", + "color": "navy", + "info": [ + { + "name": "detail=css", + "field": "CSS", + "description": "Add custom colors to your dashboard. This field should only be used by advanced users.", + "default": "", + "example": "", + "possible": "" + } + ] + } + } + } +} diff --git a/languages/ar.json b/languages/ar.json new file mode 100644 index 0000000..a1f3fef --- /dev/null +++ b/languages/ar.json @@ -0,0 +1,497 @@ +{ + "\"No Motion\" Detector": "\"لا الحركة\" كاشف", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "180 Degrees": "180 درجة", + "2-Factor Authentication": "2-عامل التوثيق", + "90 Clockwise": "90 اتجاه عقارب الساعة", + "90 Clockwise and Vertical Flip": "90 اتجاه عقارب الساعة العمودي الوجه", + "90 Counter Clockwise and Vertical Flip (default)": "90 عكس اتجاه عقارب الساعة و انعكاس عمودي (الافتراضي)", + "API": "API", + "API Key Added": "مفتاح API وأضاف", + "API Key Deleted": "مفتاح API حذف", + "API Keys": "مفاتيح API", + "APIKeyAddedText": "يمكنك استخدام هذا المفتاح الآن.", + "APIKeyDeletedText": "تم حذف مفتاح. وسوف لم يعد يعمل.", + "ASC": "ASC", + "Account Info": "معلومات الحساب", + "AccountEditText1": "لا يمكن تحريرها. تحديث الصفحة إذا كانت المشكلة لا تزال.", + "Accounts": "حسابات", + "Action for Selected": "العمل المحدد", + "Add": "إضافة", + "Add Monitor": "إضافة مراقبة", + "Add New": "إضافة جديدة", + "Admin": "المشرف", + "Advanced": "المتقدمة", + "Again": "مرة أخرى", + "All Monitors": "جميع الشاشات", + "All Monitors and Privileges": "جميع شاشات والامتيازات", + "All Warnings": "كل التحذيرات", + "Allow Next Command": "تسمح الأمر التالي في دقائق", + "Allow Next Email": "تسمح المقبل البريد الإلكتروني في غضون دقائق", + "Allow Next Trigger": "تسمح الزناد التالي في ميلي ثانية", + "Allowed IPs": "يسمح IPs", + "Analyzation Duration": "Analyzation مدة", + "Archive": "أرشيف", + "Audio Codec": "ترميز الصوت", + "Authenticate": "المصادقة", + "Auto": "السيارات", + "Autosave": "الحفظ التلقائي", + "Base64 over Websocket": "Base64 على Websocket", + "Bottom Left": "أسفل اليسار", + "Bottom Right": "أسفل اليمين", + "Browser Console Log": "المتصفح سجل وحدة", + "CPU": "وحدة المعالجة المركزية", + "CPU indicator will not work. Continuing...": "وحدة المعالجة المركزية المؤشر لا يعمل. استمرار...", + "CSS": "CSS أسلوب لوحة القيادة الخاصة بك.", + "Calendar": "التقويم", + "Camera Password": "كاميرا المرور", + "Camera Username": "الكاميرا المستخدم", + "Camera is not recording": "الكاميرا ليست تسجيل", + "CameraNotRecordingText": "الإعدادات قد تكون غير متوافقة. التحقق من الترميز. إعادة تشغيل...", + "Can Control Monitors": "يمكن التحكم في الشاشات", + "Can Delete Videos": "يمكن حذف الفيديو", + "Can Delete Videos and Events": "يمكن حذف الفيديو و الأحداث", + "Can Edit Monitor": "يمكن تحرير رصد", + "Can Get Logs": "يمكن الحصول على سجلات", + "Can Get Monitors": "يمكن الحصول على شاشات", + "Can View Monitor": "يمكن عرض الشاشة", + "Can View Snapshots": "يمكن عرض لقطات", + "Can View Streams": "يمكن عرض الجداول", + "Can View Videos": "يمكن عرض الفيديو", + "Can View Videos and Events": "يمكن عرض أشرطة الفيديو والأحداث", + "Can't Connect": "لا يمكن الاتصال", + "Center": "مركز عنوان URL", + "Chat on Discord": "الدردشة على الفتنة", + "Check": "تحقق", + "Check Signal Interval": "التحقق من إشارة الفاصل الزمني في دقائق", + "Check for Motion First": "تحقق من الحركة الأولى", + "Close": "قريب", + "Closed": "مغلقة", + "Command": "الأمر", + "Command on Trigger": "القيادة على الزناد", + "Complete Stream URL": "كاملة تيار URL", + "Confirm": "تأكيد", + "Connected": "متصل", + "Connection Type": "نوع الاتصال", + "Control": "التحكم", + "Control Error": "السيطرة على خطأ", + "ControlErrorText1": "لم يتم تمكين التحكم", + "Controllable": "يمكن السيطرة عليها", + "Country of Plates": "البلد من لوحات", + "Counts of Motion": "تهم الحركة", + "Current": "الحالي", + "Currently viewing": "حاليا عرض", + "Custom": "مخصص", + "Custom Base URL": "العرف قاعدة URL ترك فارغا لاستخدام المضيف URL", + "DB Lost.. Retrying..": "قاعدة البيانات المفقودة.. إعادة المحاولة..", + "DESC": "DESC", + "Dashboard": "لوحة القيادة", + "Dashboard Language": "لوحة أجهزة القياس في اللغة", + "Dashcam": "Dashcam", + "Dashcam (Streamer v2)": "Dashcam (غاسل v2)", + "Date Range": "نطاق التاريخ", + "Debug": "التصحيح", + "Default": "الافتراضي", + "Delete": "حذف", + "Delete Filter": "حذف الفلتر", + "Delete Matches": "حذف المباريات", + "Delete Monitor": "حذف رصد", + "Delete Motionless Video": "حذف حراك الفيديو", + "Delete Motionless Videos (Record)": "حذف حراك الفيديو (رقم قياسي)", + "Delete Selected Videos": "حذف الفيديو المختار", + "Delete Video": "حذف الفيديو", + "Delete selected": "حذف المحدد", + "DeleteMonitorText": "هل تريد حذف هذا العرض ؟ لا يمكنك استرداد. ملفات هذه الهوية ستبقى في نظام الملفات. إذا اخترت إعادة رصد مع نفس معرف الفيديو و أحداث سوف تصبح مرئية في لوحة القيادة.", + "DeleteSelectedVideosMsg": "هل تريد حذف هذا الفيديو ؟ لا يمكنك استرداد.", + "DeleteVideoMsg": "هل تريد حذف هذا الفيديو ؟ لا يمكنك استرداد.", + "Deleted": "حذف", + "Detect Objects": "الكشف عن الكائنات انظر أدناه", + "Detector": "كاشف", + "Detector Flags": "كشف أعلام", + "Detector Rate": "للكشف عن معدل (FPS)", + "DetectorText": "

عندما المربعات عرض وارتفاع ترد عليك أن مجموعة منهم إلى 640 × 480 أو أقل. هذا وسوف تحسين سرعة القراءة من الإطارات.

", + "Disable Night Vision": "تعطيل للرؤية الليلية عنوان URL", + "Disable Nightvision": "تعطيل رؤية ليلية", + "Disabled": "تعطيل", + "Documentation": "الوثائق", + "Don't show this anymore": "لا تظهر هذا بعد الآن", + "Double Quote Directory": "اقتباس مزدوجة الدليل بعض الدلائل التي تحتوي على مسافات. باستخدام هذا قد يتلف بعض الكاميرات.", + "Down": "أسفل عنوان URL", + "Down Stop": "أسفل وقف عنوان URL", + "Download": "تحميل", + "EU": "الاتحاد الأوروبي", + "Edit": "تحرير", + "Email": "البريد الإلكتروني", + "Email Details": "البريد الإلكتروني التفاصيل", + "Email on No Motion": "البريد الإلكتروني على \"لا الحركة\"", + "Email on Trigger": "البريد الإلكتروني على الزناد رسائل البريد الإلكتروني الذهاب إلى الحساب الرئيسي حامل عنوان تسجيل الدخول.", + "Enable Night Vision": "تمكين الرؤية الليلية عنوان URL", + "Enable Nightvision": "تمكن رؤية ليلية", + "Enabled": "تمكين", + "End": "نهاية", + "End Time": "نهاية الوقت", + "Ended": "انتهت", + "Enlarge": "تكبير", + "Enter this code to proceed": "أدخل هذا الرمز إلى المضي قدما", + "Equal to": "يساوي", + "Error Connecting": "حدث خطأ أثناء الاتصال", + "Event": "الحدث", + "Event Limit": "الحدث الحد", + "EventText1": "أثار الحدث الحركة في", + "EventText2": "لا يمكن أن البريد الإلكتروني صورة الملف لا يمكن الوصول إليها", + "Events": "الأحداث", + "Example": "على سبيل المثال", + "Execute Command": "تنفيذ الأوامر", + "Executed": "أعدم", + "Export": "التصدير", + "FFmpegCantStart": "FFmpeg لم تبدأ", + "FFmpegCantStartText": "تسجيل محرك هذه الكاميرا لا يمكن أن تبدأ. قد يكون هناك شيء خاطئ مع الكاميرا التكوين. إذا كان هناك أي سجلات أخرى من هذا واحد يرجى نشرها في القضايا على جيثب.", + "FFmpegTip": "FFprobe بسيط تيارات متعددة الوسائط محلل. يمكنك استخدامه لانتاج جميع أنواع المعلومات حول المدخلات بما في ذلك مدة, معدل الإطار, حجم الإطار ، إلخ.", + "FFprobe": "التحقيق", + "FactorAuthText1": "كود سوف يكون نشطا فقط لمدة 15 دقيقة. إذا كنت تسجيل الدخول مرة أخرى الموقت سيتم إعادة تعيين إلى 15 دقيقة مع نفس القانون.", + "Fatal": "قاتلة", + "Fatal Maximum Reached": "قاتلة الأقصى التوصل إلى وقف الكاميرا.", + "FatalMaximumReachedText": "JPEG كان خطأ فادح.", + "Feed-in Image Height": "تغذية في ارتفاع الصورة", + "Feed-in Image Width": "تغذية في صورة العرض", + "Fields cannot be empty": "المجالات لا يمكن أن تكون فارغة", + "File Not Exist": "الملف غير موجود", + "File Not Found": "لم يتم العثور على الملف", + "File Type": "نوع الملف", + "FileNotExistText": "لا يمكن حفظ غير متوفرة. شيء ذهب على نحو خاطئ.", + "Filename": "اسم الملف", + "Filesize": "حجم الملف", + "Filter ID": "تصفية معرف", + "Filter Matches": "تصفية المباريات", + "Filter Name": "اسم عامل التصفية", + "FilterMatchesText1": "هذا الفلتر قد استوفت الشروط.", + "FilterMatchesText2": "أشرطة الفيديو وجدت.", + "Filters": "المرشحات", + "Filters Updated": "مرشحات تحديث", + "FiltersUpdatedText": "التغييرات التي تم حفظها وتطبيقها.", + "Find Where": "تجد فيها", + "Fix": "Fix", + "Fix Video": "إصلاح الفيديو", + "FixVideoMsg": "هل تريد إصلاح هذا الفيديو ؟ لا يمكن التراجع عن هذا الإجراء.", + "Font Path": "مسار الخط", + "Font Size": "حجم الخط", + "Force Port": "القوة ميناء", + "Found Devices": "وجدت الأجهزة", + "Frame Rate": "معدل الإطار (FPS)", + "Full Frame Detection": "الإطار الكامل الكشف", + "Fullscreen": "ملء الشاشة", + "Greater Than": "أكبر من", + "Greater Than or Equal to": "أكبر من أو يساوي", + "Group Key": "المجموعة الرئيسية", + "Group Name": "اسم المجموعة", + "Grouping": "تجمع ", + "H.264 / H.265 / H.265+": "H. 264 / H. 265 / H. 265 ", + "HLS (.m3u8)": "HLS (.m3u8)", + "HLS (includes Audio)": "HLS (ويشمل الصوت)", + "HLS Audio Encoder": "HLS ترميز الصوت", + "HLS List Size": "HLS قائمة الحجم", + "HLS Preset": "HLS مسبقا", + "HLS Segment Length": "HLS قطعة طول في ثواني", + "HLS Video Encoder": "HLS ترميز الفيديو", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "Height": "ارتفاع", + "Help": "مساعدة", + "Hide List": "إخفاء قائمة", + "Hide Notes": "إخفاء الملاحظات", + "Host": "المضيف", + "Hotswap Modes (Watch-Only)": "Hotswap وسائط (مشاهدة فقط)", + "How to Record": "كيفية تسجيل", + "IP Address": "عنوان IP", + "Identity": "الهوية", + "IdentityText1": "هذا هو كيف نظام تحديد البيانات عن هذا التيار. لا يمكنك تغيير الشاشة معرف بمجرد الضغط على حفظ. إذا كنت تريد أن تجعل الشاشة معرف المزيد الإنسان للقراءة قبل المتابعة.", + "IdentityText2": "يمكنك تكرار رصد بتعديل رصد الهوية ثم الضغط على حفظ. هل يمكن استخدام معرف جهاز موجود بالفعل أو أنه سيوفر أكثر من أن الشاشة معلومات قاعدة البيانات.", + "Idle": "الخمول", + "Image Height": "ارتفاع الصورة", + "Image Location": "صورة موقع المسار المطلق أو ترك فارغا لاستخدام العالمية", + "Image Position": "صورة الموقف", + "Image Width": "صورة العرض", + "Import": "استيراد", + "Import Monitor Configuration": "استيراد رصد التكوين", + "ImportMonitorConfigurationText": "عند القيام بذلك سوف overrwrite أي تغييرات في الوقت الراهن لم يتم حفظها. التغييرات المستوردة تطبق فقط عند الضغط على حفظ.", + "In": "في", + "Incorrect Settings Chosen": "إعدادات غير صحيحة المختار", + "Indifference": "اللامبالاة", + "Input": "المدخلات", + "Input Flags": "إدخال الأعلام", + "Input Type": "نوع الإدخال", + "InputText1": "هذا المقطع يحكي شينوبي كيفية تستهلك تيار. للحصول على الأداء الأمثل محاولة ضبط الكاميرا الإعدادات الداخلية. العثور على الخيارات التالية ومجموعة منهم كما هو مبين. العثور على الكاميرا الخاصة بك يمكنك استخدام بنيت في ONVIF الماسح الضوئي من شينوبي. بعض كاميرات ONVIF تتطلب استخدام أداة إدارة إلى تعديل الإعدادات الداخلية. إذا كنت لا يمكن العثور على الكاميرات الخاصة بك يمكنك محاولة ONVIF مدير جهاز ويندوز.", + "InputText2": "
  • فراميراتي (FPS) : : 10 - 15 إطارا في الثانية ، منخفض : 2-5 إطارا في الثانية
  • I-الإطار الزمني : 80
  • نوع معدل بت : CBR (ثابت معدل بت)
  • معدل بت : بين 256kbps - 500kbps
", + "InputText3": "إذا كنت بحاجة إلى مساعدة في معرفة ما هو إدخال نوع الكاميرا الخاصة بك يمكنك أن تأخذ نظرة في الكاميرا عناوين قائمة على شينوبي الموقع.", + "Invalid JSON": "صالح سلمان", + "InvalidJSONText": "يرجى التأكد من هذا هو صالح سلمان سلسلة شينوبي رصد التكوين.", + "JPEG": "JPEG", + "JPEG (Auto Enables JPEG API)": "JPEG (السيارات تمكن JPEG API)", + "JPEG API": "JPEG API لقطة (cgi-bin)", + "JPEG Error": "JPEG خطأ", + "JPEG Mode": "وضع JPEG", + "JPEGErrorText": "كان هناك مشكلة في الحصول على البيانات من الكاميرا الخاصة بك.", + "Leave blank for random.": "ترك فارغا عشوائية.", + "Left": "ترك عنوان URL", + "Left Stop": "غادر وقف عنوان URL", + "Less Than": "أقل من", + "Less Than or Equal to": "أقل من أو يساوي", + "Like": "مثل", + "Lisence Plate Detector": "رخصة لوحة كاشف", + "List Toggle": "قائمة تبديل", + "Live Stream Toggle": "بث مباشر تبديل", + "Live View": "عرض لايف", + "Local": "المحلية", + "Log Level": "سجل مستوى", + "Log Signal Event": "سجل إشارة الحدث من جانب العميل فقط", + "Logging": "تسجيل", + "Login": "تسجيل الدخول", + "Logout": "خروج", + "Logs": "سجلات", + "MB": "MB", + "MJPEG": "MJPEG", + "MP4 (copy, libx264, libx265)": "MP4 (نسخ ، libx264, libx265)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)", + "MailError": "البريد خطأ : لا يمكن إرسال البريد الإلكتروني التحقق من conf.json. تخطي أي ملامح الاعتماد على البريدية.", + "Matches": "مباريات", + "Max Storage Amount": "ماكس تخزين كمية في ميغا بايت", + "Mode": "وضع", + "Monitor": "رصد", + "Monitor Added by user": "رصد المضافة من قبل المستخدم.", + "Monitor Capture Rate": "رصد معدل التقاط (FPS)", + "Monitor Groups": "رصد مجموعات", + "Monitor ID": "رصد ID", + "Monitor Idling": "رصد تسكع", + "Monitor Name": "رصد اسم", + "Monitor Settings": "إعدادات الشاشة", + "Monitor Stopped": "رصد توقف", + "Monitor Updated by user": "مراقبة تحديث من قبل المستخدم.", + "Monitor mode changed": "مراقبة الوضع تغير", + "Monitor mode is already": "رصد وضع بالفعل", + "Monitor or Key does not exist.": "مراقبة أو عدم وجود مفتاح.", + "MonitorIdlingText": "مراقبة الدورة وقد أمر إلى الخمول.", + "MonitorStoppedText": "مراقبة الدورة وقد أمر التوقف.", + "Monitors": "شاشات", + "Monitors per row": "شاشات لكل صف على المونتاج", + "Montage": "المونتاج", + "Motion GUI": "الحركة واجهة المستخدم الرسومية", + "Motion Meter": "الحركة متر", + "Name": "اسم", + "No": "لا", + "No Audio": "لا الصوت", + "No Data": "لا توجد بيانات", + "No Events found for this video": "لا الأحداث وجدت هذا الفيديو", + "No Group with this key exists": "أي جماعة مع هذا المفتاح موجود", + "No Monitor Found, Ignoring Request": "لا مراقبة وجدت تجاهل الطلب", + "No Rotation": "لا دوران", + "No such file": "لا يوجد مثل هذا الملف", + "NoMotionEmailText1": "لا الحركة", + "NoMotionEmailText2": "لم يكن هناك أي حركة الكشف على الكاميرا", + "NoVideosFoundForDateRange": "لا أشرطة الفيديو الموجودة في هذا النطاق الزمني. محاولة تحديد بداية التاريخ إلى الوراء.", + "Not Authorized": "لا يؤذن", + "Not Connected": "غير متصل", + "Not Equal to": "لا يساوي", + "Not In": "لا في", + "Not Matches": "لا يطابق", + "Not Permitted": "لا يسمح", + "Not an Administrator Account": "لا حساب مسؤول", + "NotAuthorizedText1": "لا يحق تقديم init الأمر مع \"مصادقة\",\"كه\", \"uid\"", + "Notes": "ملاحظات", + "NotesPlacholder": "التعليقات كنت تريد أن تترك هذه الكاميرات الإعدادات.", + "Number of Days to keep": "عدد أيام الاحتفاظ", + "ONVIF": "ONVIF", + "ONVIF Scanner": "ONVIF الماسح الضوئي", + "ONVIFnote": "اكتشاف ONVIF الأجهزة على الشبكات خارج الخاص بك أو اتركه فارغا لمسح شبكة الاتصال الحالية الخاصة بك.
اسم المستخدم وكلمة المرور يمكن أن تترك فارغة.", + "OpenCV Cascades": "بنسف شلالات", + "Order Streams": "ترتيب الجداول", + "Output Method": "أسلوب الإخراج", + "Password": "كلمة المرور", + "Password Again": "كلمة المرور مرة أخرى", + "Passwords don't match": "كلمات السر لا تتطابق", + "Paste JSON here.": "لصق JSON هنا.", + "Path": "المسار", + "Permissions": "أذونات", + "Points": "نقاط عند إضافة نقاط انقر على حافة المضلع.", + "Port": "ميناء", + "Position X": "موقف X", + "Position Y": "موقف Y", + "Power Video Viewer": "فيديو المشاهد", + "Power Viewer": "السلطة المشاهد", + "Preferences": "تفضيلات", + "Preset": "مسبقا", + "Probe Size": "التحقيق الحجم", + "Process Crashed for Monitor": "عملية تحطمت على رصد", + "Process Unexpected Exit": "عملية خروج غير متوقع", + "Profile": "الملف الشخصي", + "Quality": "جودة 1 عالية ، 23 منخفضة", + "Query": "الاستعلام", + "RAM": "ذاكرة الوصول العشوائي", + "RTSP": "RTSP", + "RTSP Transport": "RTSP النقل", + "Range or Single": "مجموعة أو واحد", + "Rate": "معدل (FPS)", + "Record": "سجل", + "Record File Type": "تسجيل نوع الملف", + "Record Height": "سجل ارتفاع", + "Record Video Filter": "تسجيل الفيديو فلتر", + "Record Width": "سجل العرض", + "Recording": "تسجيل", + "Recording Flags": "تسجيل الأعلام", + "Recording Segment Interval": "تسجيل الجزء الفاصل الزمني في دقائق", + "Recording Timeout": "تسجيل مهلة في دقائق", + "Recording Timestamp": "تسجيل الزمني", + "Recording Watermark": "تسجيل العلامة المائية", + "RecordingText": "فمن المستحسن أن تقوم بتعيين تسجيل نوع الملف إلى WebMMP4 و ترميز الفيديو إلى libvpxنسخ أو libx264 لأن إدخال نوع هو .", + "Refresh List of Cascades": "تحديث قائمة شلالات", + "Region Editor": "المنطقة محرر", + "Region Name": "اسم المنطقة", + "RegionNote": "النقاط يتم حفظها فقط عند الضغط حفظ على إعدادات الشاشة نافذة.", + "Regions": "المناطق", + "Remember Me": "تذكر لي", + "Reset Timer": "إعادة تعيين جهاز ضبط الوقت", + "Restarting Process": "إعادة تشغيل العملية", + "Retry Connection": "إعادة المحاولة اتصال عدد المرات التي يسمح تفشل", + "Retrying...": "إعادة المحاولة...", + "Right": "صحيح عنوان URL", + "Right Stop": "صحيح وقف عنوان URL", + "Rotate": "تدوير", + "Save": "حفظ", + "Save Directory": "حفظ الدليل", + "Save Events to SQL": "حفظ الأحداث إلى SQL", + "Save Log in SQL": "حفظ سجل في SQL وهذا يمكن أن تملأ بسرعة.", + "Save as": "حفظ باسم", + "Saved Filters": "حفظ الفلاتر", + "Scan Settings": "إعدادات المسح الضوئي", + "Search": "البحث", + "Send Frames": "إرسال إطارات دفع الإطارات ليتم تحليلها", + "Separate with commas, no spaces": "منفصلة بفواصل, بدون مسافات", + "Set to Watch Only": "تعيين مشاهدة فقط", + "Settings": "الإعدادات", + "Settings Changed": "تغيير الإعدادات", + "SettingsChangedText": "إعدادات تم حفظها وتطبيقها.", + "Shinobi": "شينوبي", + "Shinobi Streamer": "شينوبي غاسل", + "Show Logs": "تظهر سجلات", + "Silent": "الصمت", + "Simple": "بسيطة", + "Size (mb)": "الحجم (ميجا بايت)", + "Snapshot": "لقطة", + "Snapshot Flags": "لقطة الأعلام", + "Snapshots": "لقطات", + "Sort By": "فرز حسب", + "Start": "تبدأ", + "Start Recording": "بدء التسجيل", + "Start Time": "وقت البدء", + "Started": "بدأت", + "Status Indicator": "مؤشر حالة", + "Stop URL": "وقف URL", + "Stream": "تيار", + "Stream Flags": "تيار الأعلام", + "Stream Timestamp": "تيار الزمني", + "Stream Type": "تيار من نوع", + "Stream Watermark": "تيار مائية", + "Stream to YouTube": "تيار يوتيوب", + "Stream to YouTube Flags": "تيار يوتيوب الأعلام", + "StreamText": "

هذا القسم سوف تعين الابتدائي تيار الأسلوب وإعدادات. هذا التيار سوف يتم عرضها في لوحة القيادة. إذا اخترت استخدام HLS, JPEG, أو MJPEG ثم يمكنك تستهلك تيار من خلال البرامج الأخرى.

استخدام JPEG تيار أساسا إيقاف البث الأساسية يستخدم اللقطة بن للحصول على إطارات.

", + "Streamer": "غاسل", + "Streams": "تيارات", + "Superuser": "الخارق", + "Switch on for Still Image": "التبديل على صورة ثابتة", + "TCP": "TCP", + "Text Box Color": "النص مربع اللون", + "Text Color": "لون النص", + "Time-lapse": "الوقت الفاصل بين", + "Time-lapse Tool": "الوقت الفاصل بين أداة", + "Timeout": "مهلة", + "Timeout Reset on Next Motion": "مهلة إعادة تعيين على الحركة القادمة", + "Toggle Sidebar": "تبديل الشريط الجانبي", + "Top Left": "أعلى اليسار", + "Top Right": "أعلى اليمين", + "Trigger Record": "الزناد سجل", + "Trigger Successful": "الزناد ناجحة", + "UDP": "UDP", + "URL": "URL", + "URL Stop Timeout": "URL وقف مهلة تشغيل إيقاف URL بعد X ثانية", + "US": "لنا", + "Unable to Launch": "قادر على إطلاق", + "UnabletoLaunchText": "الرجاء حفظ رصد جديدة أولا. ثم محاولة إطلاق محرر المنطقة.", + "Up": "حتى عنوان URL", + "Up Stop": "حتى وقف عنوان URL", + "Username": "اسم المستخدم", + "Value": "القيمة", + "Video": "فيديو", + "Video Codec": "ترميز الفيديو", + "Video Filter": "فيديو مرشح", + "Video Finished": "الفيديو النهائي", + "Video Length (minutes) and Motion Count per video": "طول الفيديو (دقيقة) و الحركة الاعتماد في الفيديو", + "Video Record Rate": "الفيديو سجل معدل (FPS)", + "Video Status": "فيديو حالة", + "Video and Time Span (Minutes)": "فيديو من الزمن (دقيقة)", + "Videos": "الفيديو", + "Videos List": "قائمة أشرطة الفيديو", + "Watch": "مشاهدة", + "Watch Only": "مشاهدة فقط", + "WebDAV": "WebDAV", + "WebM (libvpx)": "WebM (libvpx)", + "Webdav Error": "خطأ Webdav", + "WebdavErrorText": "لا يمكن حفظ. هل جعل الكاميرا المجلدات داخل اخترتها حفظ الدليل ؟ ", + "Webhook": "Webhook", + "Webhook URL": "Webhook URL", + "Width": "العرض", + "Yes": "نعم", + "Zoom In": "التكبير في عنوان URL", + "Zoom In Stop": "التكبير في التوقف عن عنوان URL", + "Zoom Out": "تصغير عنوان URL", + "Zoom Out Stop": "تصغير وقف عنوان URL", + "a day": "اليوم", + "a few seconds": "بضع ثوان", + "a minute": "دقيقة", + "a month": "شهر", + "a year": "في السنة", + "aac": "الجميح للسيارات", + "aac (Default)": "الجميح للسيارات (افتراضي)", + "ac3": "ac3", + "ago": "قبل", + "an hour": "ساعة", + "blankPassword": "تترك فارغة إلى الحفاظ على نفس كلمة المرور", + "calendar": "التقويم", + "clientStreamFailedattemptingReconnect": "العميل ctream تحقق فشلت محاولة إعادة الاتصال.", + "confirmDeleteFilter": "هل تريد حذف هذا الفلتر ؟ لا يمكنك استرداد.", + "copy": "نسخ", + "days": "أيام", + "dropBoxSuccess": "النجاح! الملفات المحفوظة إلى دروببوإكس الخاص بك.", + "for Global Access": "من أجل الوصول العالمي", + "hours": "ساعات", + "in": "في", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis (الافتراضي)", + "libvpx (Default)": "libvpx (الافتراضي)", + "libvpx-vp9": "libvpx-vp9", + "libx264": "libx264", + "libx264 (Default)": "libx264 (الافتراضي)", + "libx265": "libx265", + "minutes": "دقائق", + "modifyVideoText1": "طريقة لا وجود لها. تحقق للتأكد من أن آخر قيمة URL ليست فارغة.", + "monitorEditFailedMaxReached": "حسابك قد بلغ أقصى عدد من الكاميرات التي يمكن إنشاؤها. التحدث إلى مسؤول إذا كنت ترغب في تغيير هذا.", + "monitorEditText1": "بيانات غير صالحة ، تحقق لمعرفة هذا هو صالح استيراد السلسلة.", + "monitorEditText2": "غير صالحة تفاصيل السلسلة. تحقق لمعرفة ما هو سلسلة JSON و غير منتظم وجوه يتم تمريرها.", + "monitorGetText1": "الطلب غير المكتمل ، وإزالة الماضي مائل في URL أو وضع مقبول القيمة.", + "months": "أشهر", + "noSpecialCharacters": "بدون مسافات أو أحرف خاصة.", + "on": "على", + "on Error": "على خطأ", + "startUpText0": "حجم التحقق من أشرطة الفيديو", + "startUpText1": "الغاية من حجم التحقق من أشرطة الفيديو", + "startUpText2": "جميع المستخدمين فحص الانتظار لإغلاق الملفات المفتوحة وإزالة الملفات على حد المستخدم", + "startUpText3": "في انتظار أن تعطي لم تنته الفيديو تحقق بعض الوقت. 3 ثوان.", + "startUpText4": "بدأت كل مجموعة شاشات لمشاهدة وتسجيل", + "startUpText5": "شينوبي جاهز.", + "superAdminText": "\"السوبر.سلمان\" لا وجود لها. الرجاء إعادة تسمية \"سوبر.العينة.سلمان\" إلى \"السوبر.سلمان\".", + "superAdminTitle": "شينوبي : المشرف المميز", + "total": "مجموع", + "undefined": "غير معرف", + "updateKeyText1": "\"updateKey\" مفقود من \"conf.json\", لا يمكن أن تفعل التحديثات هذه الطريقة حتى يمكنك إضافته.", + "updateKeyText2": "\"updateKey\" غير صحيحة.", + "years": "سنوات" +} diff --git a/languages/bn.json b/languages/bn.json new file mode 100644 index 0000000..2d9adcf --- /dev/null +++ b/languages/bn.json @@ -0,0 +1,496 @@ +{ + "\"No Motion\" Detector": "\"কোন গতি\" আবিষ্কারক", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "180 Degrees": "180 ডিগ্রী", + "2-Factor Authentication": "2 ফ্যাক্টর প্রমাণীকরণ", + "90 Clockwise": "ঘড়ির কাঁটার দিকে 90", + "90 Clockwise and Vertical Flip": "90 ঘড়ির কাঁটার দিকে এবং উল্লম্ব উল্টানো", + "90 Counter Clockwise and Vertical Flip (default)": "90 পাল্টা ঘড়ির কাঁটার দিকে এবং উল্লম্ব উল্টানো (ডিফল্ট)", + "API": "এপিআই", + "API Key Added": "API কী যোগ করা হয়েছে", + "API Key Deleted": "API কী মুছে ফেলা", + "API Keys": "API কী", + "APIKeyAddedText": "আপনি এই ব্যবহার করতে পারেন কী এখন.", + "APIKeyDeletedText": "কী মুছে ফেলা হয়েছে. এটা আর কাজ.", + "ASC": "ASC", + "Account Info": "অ্যাকাউন্ট তথ্য", + "AccountEditText1": "না পারে সম্পাদনা করুন. রিফ্রেশ পাতা যদি সমস্যা চলতে থাকে.", + "Accounts": "অ্যাকাউন্ট", + "Action for Selected": "কর্ম জন্য নির্বাচিত", + "Add": "যোগ", + "Add Monitor": "যোগ মনিটর", + "Add New": "নতুন যুক্ত করুন", + "Admin": "অ্যাডমিন", + "Advanced": "উন্নত", + "Again": "আবার", + "All Monitors": "সব মনিটর", + "All Monitors and Privileges": "সব মনিটর এবং বিশেষাধিকার", + "All Warnings": "সব সতর্কবার্তা", + "Allow Next Command": "অনুমতি পরবর্তী কমান্ড মিনিটের মধ্যে", + "Allow Next Email": "অনুমতি পরবর্তী ইমেইল মিনিটের মধ্যে", + "Allow Next Trigger": "অনুমতি পরবর্তী ট্রিগার মিলিসেকেন্ডে ব্যক্ত", + "Allowed IPs": "অনুমোদিত আইপিএস", + "Analyzation Duration": "Analyzation সময়কাল", + "Archive": "আর্কাইভ", + "Audio Codec": "অডিও কোডেক", + "Authenticate": "প্রমাণীকরণ", + "Auto": "অটো", + "Autosave": "স্বয়ংসংরক্ষিত", + "Base64 over Websocket": "Base64 উপর Websocket", + "Bottom Left": "নীচে বাম", + "Bottom Right": "নীচের অংশে ডানদিকে", + "Browser Console Log": "ব্রাউজার কনসোল লগ", + "CPU": "CPU-র", + "CPU indicator will not work. Continuing...": "CPU-র সূচক কাজ করবে না. অব্যাহত...", + "CSS": "CSS এর শৈলী আপনার ড্যাশবোর্ড.", + "Calendar": "ক্যালেন্ডার", + "Camera Password": "ক্যামেরা পাসওয়ার্ড", + "Camera Username": "ক্যামেরা ব্যবহারকারীর নাম", + "Camera is not recording": "ক্যামেরা নয়, রেকর্ডিং", + "CameraNotRecordingText": "সেটিংস বেমানান হতে পারে. পরীক্ষা এনকোডার. রিস্টার্ট...", + "Can Control Monitors": "নিয়ন্ত্রণ করতে পারেন মনিটর", + "Can Delete Videos": "মুছে দিতে পারেন ভিডিও", + "Can Delete Videos and Events": "মুছে দিতে পারেন ভিডিও এবং ঘটনা", + "Can Edit Monitor": "সম্পাদনা করতে পারেন নিরীক্ষণ", + "Can Get Logs": "পেতে পারেন, লগ", + "Can Get Monitors": "পেতে পারেন মনিটর", + "Can View Monitor": "দেখতে পারেন, নিরীক্ষণ", + "Can View Snapshots": "স্ন্যাপশট দেখতে পারেন", + "Can View Streams": "দেখতে পারেন স্ট্রিম", + "Can View Videos": "করতে পারেন, দেখুন ভিডিও", + "Can View Videos and Events": "করতে পারেন, দেখুন ভিডিও এবং ঘটনা", + "Can't Connect": "সংযোগ করতে পারবেন না পারে", + "Center": "কেন্দ্র URL ঠিকানা", + "Chat on Discord": "চ্যাট বিভেদ", + "Check": "পরীক্ষা", + "Check Signal Interval": "পরীক্ষা সংকেত ব্যবধান মিনিটের মধ্যে", + "Check for Motion First": "পরীক্ষা গতি জন্য প্রথম", + "Close": "বন্ধ", + "Closed": "বন্ধ", + "Command": "কমান্ড", + "Command on Trigger": "কমান্ড ট্রিগার", + "Complete Stream URL": "সম্পূর্ণ স্ট্রিম URL", + "Confirm": "নিশ্চিত", + "Connected": "সংযুক্ত", + "Connection Type": "সংযোগের ধরন", + "Control": "নিয়ন্ত্রণ", + "Control Error": "কন্ট্রোল ত্রুটি", + "ControlErrorText1": "নিয়ন্ত্রণ সক্রিয় করা হয় না", + "Controllable": "নিয়ন্ত্রণযোগ্য", + "Country of Plates": "দেশ প্লেট", + "Counts of Motion": "সংখ্যা, গতি", + "Current": "বর্তমান", + "Currently viewing": "বর্তমানে দেখছেন", + "Custom": "কাস্টম", + "Custom Base URL": "কাস্টম বেস URL ফাঁকা ছেড়ে দিন ব্যবহার করে হোস্ট URL টি", + "DB Lost.. Retrying..": "ডাটাবেস হারিয়ে.. Retrying..", + "DESC": "নিম্নক্রমে", + "Dashboard": "ড্যাশবোর্ড", + "Dashboard Language": "ড্যাশবোর্ড ভাষা", + "Dashcam": "Dashcam", + "Dashcam (Streamer v2)": "Dashcam (আলোকরশ্মি v2)", + "Date Range": "তারিখ পরিসীমা", + "Debug": "ডিবাগ", + "Default": "ডিফল্ট", + "Delete": "মুছে দিন", + "Delete Filter": "মুছে দিন, ফিল্টার", + "Delete Matches": "মুছে ম্যাচ", + "Delete Monitor": "মুছে মনিটর", + "Delete Motionless Video": "মুছে নিস্পন্দ ভিডিও", + "Delete Motionless Videos (Record)": "মুছে নিস্পন্দ ভিডিও (রেকর্ড)", + "Delete Selected Videos": "মুছে ফেলুন ভিডিও", + "Delete Video": "মুছে ভিডিও", + "Delete selected": "মুছে ফেলুন", + "DeleteMonitorText": "আপনি মুছে ফেলতে চান, এই নিরীক্ষণ? আপনি পুনরুদ্ধার করা সম্ভব না, এটা. ফাইল জন্য এই আইডি থাকবে ফাইলসিস্টেম. যদি আপনি চয়ন করতে পুনঃ একটি মনিটর সঙ্গে একই আইডি ভিডিও এবং ঘটনা হয়ে যাবে দৃশ্যমান ড্যাশবোর্ড.", + "DeleteSelectedVideosMsg": "আপনি মুছে ফেলতে চান, এই ভিডিও? আপনি পুনরুদ্ধার করা সম্ভব না তাদের.", + "DeleteVideoMsg": "আপনি মুছে ফেলতে চান, এই ভিডিও? আপনি পুনরুদ্ধার করা সম্ভব না, এটা.", + "Deleted": "মুছে ফেলা", + "Detect Objects": "সনাক্ত বস্তু নিচে দেখুন", + "Detector": "আবিষ্কারক", + "Detector Flags": "আবিষ্কারক পতাকা", + "Detector Rate": "আবিষ্কারক হার (FPS যে)", + "DetectorText": "

যখন প্রস্থ এবং উচ্চতা বাক্সে দেখানো হয়, আপনি সেট করা উচিত তাদের 640x480 বা নিচে. এই হবে নিখুত, গতি পড়া ফ্রেম.

", + "Disable Night Vision": "নিষ্ক্রিয় রাতে দৃষ্টি URL ঠিকানা", + "Disable Nightvision": "নিষ্ক্রিয় Nightvision", + "Disabled": "প্রতিবন্ধী", + "Documentation": "ডকুমেন্টেশন", + "Don't show this anymore": "প্রদর্শন করবেন না, এই আর", + "Double Quote Directory": "ডবল উদ্ধৃতি ডিরেক্টরি কিছু ডিরেক্টরি আছে স্পেস. এই ব্যবহার করে বিপর্যস্ত হতে পারে, কিছু ক্যামেরা.", + "Down": "নিচে URL ঠিকানা", + "Down Stop": "নিচে বন্ধ URL ঠিকানা", + "Download": "ডাউনলোড", + "EU": "ইইউ", + "Edit": "সম্পাদনা", + "Email": "ইমেইল", + "Email Details": "ইমেইল বিস্তারিত", + "Email on No Motion": "ইমেইল, \"কোন গতি\"", + "Email on Trigger": "ইমেইল উপর ট্রিগার ইমেল যান প্রধান অ্যাকাউন্ট ধারক এর লগইন ঠিকানা.", + "Enable Night Vision": "সক্রিয় নাইট দৃষ্টি URL ঠিকানা", + "Enable Nightvision": "সক্রিয় Nightvision", + "Enabled": "সক্রিয়", + "End": "শেষ", + "End Time": "শেষ সময়", + "Ended": "শেষ", + "Enlarge": "বিবর্ধন", + "Enter this code to proceed": "এই কোড লিখুন এগিয়ে যেতে", + "Equal to": "সমান", + "Error Connecting": "সংযোগ ত্রুটি", + "Event": "ইভেন্ট", + "Event Limit": "ইভেন্ট সীমা", + "EventText1": "সূত্রপাত গতি এ ঘটনা", + "EventText2": "না পারে, ইমেইল, ইমেজ ফাইল ছিল না, প্রবেশযোগ্য", + "Events": "ঘটনা", + "Example": "উদাহরণ", + "Execute Command": "চালানো কমান্ড", + "Executed": "মৃত্যুদন্ড কার্যকর", + "Export": "রপ্তানি", + "FFmpegCantStart": "FFmpeg শুরু করতে পারে না", + "FFmpegCantStartText": "রেকর্ডিং ইঞ্জিন জন্য এই ক্যামেরা শুরু করতে পারে না. হতে পারে, কিছু ভুল আপনার ক্যামেরা সঙ্গে কনফিগারেশন. যদি সেখানে হয় কোন লগ তুলনায় অন্যান্য, এই এক পোস্ট করুন তাদের সমস্যা Github উপর.", + "FFmpegTip": "FFprobe একটি সহজ মাল্টিমিডিয়া স্ট্রিম বিশ্লেষক. আপনি এটি ব্যবহার করতে পারেন আউটপুট সব ধরণের তথ্য সম্পর্কে একটি ইনপুট সহ, সময়কাল, ফ্রেম রেট, ফ্রেম সাইজ, ইত্যাদি.", + "FFprobe": "প্রোবের", + "FactorAuthText1": "কোড কেবল তখনই সক্রিয় করা হবে 15 মিনিটের জন্য. যদি আপনি আবার লগইন হবে টাইমার রিসেট করার 15 মিনিট একই সঙ্গে কোড.", + "Fatal": "মারাত্মক", + "Fatal Maximum Reached": "মারাত্মক সর্বোচ্চ পৌঁছেছেন বাঁধন ক্যামেরা.", + "FatalMaximumReachedText": "কোন JPEG ত্রুটি ছিল মারাত্মক.", + "Feed-in Image Height": "ফিড-ইন ইমেজ উচ্চতা", + "Feed-in Image Width": "ফিড-ইন ইমেজ প্রস্থ", + "Fields cannot be empty": "ক্ষেত্র হতে পারে না, খালি", + "File Not Exist": "ফাইল উপস্থিত না", + "File Not Found": "ফাইল পাওয়া যায় না", + "File Type": "ফাইল টাইপ", + "FileNotExistText": "সংরক্ষণ করতে পারবেন না, অ existant ফাইল. কিছু ভুল হয়েছে.", + "Filename": "ফাইলের নাম", + "Filesize": "Filesize", + "Filter ID": "ফিল্টার আইডি", + "Filter Matches": "ফিল্টার ম্যাচ", + "Filter Name": "ফিল্টার নাম", + "FilterMatchesText1": "এই ফিল্টার শর্ত পূরণ করা হয়েছে.", + "FilterMatchesText2": "ভিডিও পাওয়া যায়.", + "Filters": "ফিল্টার", + "Filters Updated": "ফিল্টার আপডেট করা হয়েছে", + "FiltersUpdatedText": "আপনার পরিবর্তনগুলি সংরক্ষণ করা হয়েছে এবং প্রয়োগ.", + "Find Where": "এটি যেখানে", + "Fix": "ফিক্স", + "Fix Video": "ফিক্স ভিডিও", + "FixVideoMsg": "আপনি কি করতে চান ঠিক এই ভিডিও? আপনি পূর্বাবস্থা করতে পারবেন না, এই কর্ম.", + "Font Path": "ফন্ট পথ", + "Font Size": "ফন্টের আকার", + "Force Port": "বল পোর্ট", + "Found Devices": "পাওয়া ডিভাইসের", + "Frame Rate": "ফ্রেম হার (FPS যে)", + "Full Frame Detection": "পুরো ফ্রেম সনাক্তকরণ", + "Fullscreen": "পর্দা জুড়ে প্রদর্শন", + "Greater Than": "তার চেয়ে অনেক বেশী", + "Greater Than or Equal to": "তার চেয়ে অনেক বেশী বা সমান", + "Group Key": "গ্রুপ কী", + "Group Name": "গ্রুপের নাম", + "Grouping": "জোট ", + "H.264 / H.265 / H.265+": "H. 264 / H. 265 / H. 265 ", + "HLS (.m3u8)": "HLS (.m3u8)", + "HLS (includes Audio)": "HLS (অন্তর্ভুক্ত অডিও)", + "HLS Audio Encoder": "HLS অডিও এনকোডার", + "HLS List Size": "HLS তালিকা আকার", + "HLS Preset": "HLS প্রিসেট", + "HLS Segment Length": "HLS সেগমেন্ট দৈর্ঘ্য সেকেন্ডের মধ্যে", + "HLS Video Encoder": "HLS ভিডিও এনকোডার", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "Height": "উচ্চতা", + "Help": "সাহায্য", + "Hide List": "আড়াল তালিকা", + "Hide Notes": "আড়াল নোট", + "Host": "হোস্ট", + "Hotswap Modes (Watch-Only)": "Hotswap মোড (দেখুন শুধুমাত্র)", + "How to Record": "রেকর্ড কিভাবে", + "IP Address": "আইপি ঠিকানা", + "Identity": "পরিচয়", + "IdentityText1": "কিভাবে এই সিস্টেম সনাক্ত করা হবে এই জন্য তথ্য প্রবাহ. আপনি পরিবর্তন করতে পারবেন না, মনিটর আইডি আছে একবার আপনি চাপা সংরক্ষণ করুন. যদি আপনি চান আপনি করতে পারেন নিরীক্ষণ, আইডি , আরো মানুষের পাঠযোগ্য আপনি অবিরত আগে.", + "IdentityText2": "আপনি প্রতিলিপি করতে পারেন একটি মনিটর পরিবর্তন করে মনিটর আইডি , তারপর টিপে সংরক্ষণ করুন. আপনি না ব্যবহার করে আইডি এর একটি মনিটর যে ইতিমধ্যেই বিদ্যমান, অথবা এটি সংরক্ষণ করতে হবে যে ওভার মনিটর এর ডাটাবেস তথ্য.", + "Idle": "অলস", + "Image Height": "ইমেজ উচ্চতা", + "Image Location": "ইমেজ অবস্থান পরম পাথ অথবা ফাঁকা ছেড়ে দিন ব্যবহার করতে গ্লোবাল", + "Image Position": "ইমেজ অবস্থান", + "Image Width": "চিত্র প্রস্থ", + "Import": "আমদানি", + "Import Monitor Configuration": "আমদানি মনিটর কনফিগারেশন", + "ImportMonitorConfigurationText": "এই কাজ হবে overrwrite কোন পরিবর্তন বর্তমানে সংরক্ষিত নয়. আমদানি পরিবর্তন হবে শুধুমাত্র প্রয়োগ করা হলে, আপনি প্রেস সংরক্ষণ করুন.", + "In": "এ", + "Incorrect Settings Chosen": "ভুল সেটিংস চয়ন", + "Indifference": "অযত্ন", + "Input": "ইনপুট", + "Input Flags": "ইনপুট পতাকা", + "Input Type": "ইনপুট টাইপ", + "InputText1": "এই অধ্যায় বলে Shinobi গ্রাস কিভাবে একটি স্ট্রিম. অনুকূল কর্ম সঞ্চালনের জন্য টিউন করার চেষ্টা করুন, আপনার ক্যামেরা এর অভ্যন্তরীণ সেটিংস. এটি নিম্নলিখিত অপশন এবং তাদের সেট হিসাবে দেখানো হয়েছে. খুঁজে বের করতে আপনার ক্যামেরা ব্যবহার করতে পারেন বিল্ট ইন ONVIF স্ক্যানার এর Shinobi. কিছু ONVIF ক্যামেরা ব্যবহারের প্রয়োজন একটি ম্যানেজমেন্ট টুল পরিবর্তন করতে তাদের অভ্যন্তরীণ সেটিংস. যদি আপনি না করতে পারেন, এটি আপনার ক্যামেরা আপনি চেষ্টা করতে পারেন, ONVIF ডিভাইস ম্যানেজার উইন্ডোজের জন্য.", + "InputText2": "
  • ফ্রেমরেট (FPS) : উচ্চ : 10 - 15 FPS কম : 2-5 FPS
  • আমি-ফ্রেম ব্যবধান : 80
  • বিট রেট টাইপ : CBR (ধ্রুবক বিট রেট)
  • বিট রেট : মধ্যে 256kbps - 500kbps
", + "InputText3": "যদি আপনি সাহায্য প্রয়োজন figuring আউট কি ইনপুট টাইপ আপনার ক্যামেরা, হয়, আপনি গ্রহণ করতে পারেন, একটি বর্ণন মধ্যে ক্যামেরা Url গুলি তালিকা উপর Shinobi ওয়েবসাইট.", + "Invalid JSON": "অবৈধ JSON", + "InvalidJSONText": "দয়া করে নিশ্চিত করুন, এটি একটি বৈধ JSON স্ট্রিং জন্য Shinobi মনিটর কনফিগারেশন.", + "JPEG": "কোন JPEG", + "JPEG (Auto Enables JPEG API)": "কোন JPEG (অটো সক্ষম হবেন, কোন JPEG, এপিআই)", + "JPEG API": "কোন JPEG এপিআই স্ন্যাপশট (cgi-bin)", + "JPEG Error": "কোন JPEG ত্রুটি", + "JPEG Mode": "কোন JPEG মোড", + "JPEGErrorText": "সেখানে ছিল একটি ইস্যু পেয়ে তথ্য আপনার ক্যামেরা থেকে.", + "Leave blank for random.": "ফাঁকা ছেড়ে দিন জন্য র্যান্ডম.", + "Left": "বাম URL ঠিকানা", + "Left Stop": "বাম বন্ধ URL ঠিকানা", + "Less Than": "কম", + "Less Than or Equal to": "কম বা সমান", + "Like": "মত", + "Lisence Plate Detector": "অনুজ্ঞাপত্র প্লেট আবিষ্কারক", + "List Toggle": "তালিকা টগল", + "Live Stream Toggle": "লাইভ স্ট্রিম টগল", + "Live View": "লাইভ দেখুন", + "Local": "স্থানীয়", + "Log Level": "লগ স্তর", + "Log Signal Event": "লগ সংকেত ইভেন্ট ক্লায়েন্ট প্রান্তের শুধুমাত্র", + "Logging": "লগিং", + "Login": "লগইন", + "Logout": "লগ আউট", + "Logs": "লগ", + "MB": "MB", + "MJPEG": "MJPEG", + "MP4 (copy, libx264, libx265)": "আছে MP4 (কপি, libx264, libx265)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4 (.আছে mp4 / .ts)", + "MailError": "মেইল ত্রুটি : যায়নি পাঠাতে ইমেইল চেক conf.json. কুঁদন কোন বৈশিষ্ট্য উপর নির্ভর মেইলিং.", + "Matches": "ম্যাচ", + "Max Storage Amount": "সর্বোচ্চ স্টোরেজ পরিমাণ মেগাবাইটের মধ্যে", + "Mode": "মোড", + "Monitor": "মনিটর", + "Monitor Added by user": "মনিটর যোগ করা হয়েছে ব্যবহারকারী দ্বারা.", + "Monitor Capture Rate": "মনিটর ক্যাপচার হার (FPS যে)", + "Monitor Groups": "মনিটর গ্রুপ", + "Monitor ID": "মনিটর আইডি", + "Monitor Idling": "মনিটর আলসে", + "Monitor Name": "মনিটর নাম", + "Monitor Settings": "মনিটর সেটিংস", + "Monitor Stopped": "মনিটর বন্ধ", + "Monitor Updated by user": "মনিটর দ্বারা আপডেট ব্যবহারকারী.", + "Monitor mode changed": "মনিটর মোড পরিবর্তন", + "Monitor mode is already": "মনিটর মোড ইতিমধ্যে", + "Monitor or Key does not exist.": "মনিটর বা কী নেই.", + "MonitorIdlingText": "মনিটর অধিবেশন করার নির্দেশ দেয়া হয়েছে অলস.", + "MonitorStoppedText": "মনিটর অধিবেশন বন্ধ করার নির্দেশ দেয়া হয়েছে.", + "Monitors": "মনিটর", + "Monitors per row": "মনিটর প্রতি সারির জন্য পূর্ণাঙ্গতা", + "Montage": "পূর্ণাঙ্গতা", + "Motion GUI": "গতি গ্রাফিক্যাল ইউজার ইন্টারফেস", + "Motion Meter": "গতি মিটার", + "Name": "নাম", + "No": "কোন", + "No Audio": "কোন অডিও", + "No Data": "কোন তথ্য", + "No Events found for this video": "কোন ঘটনা পাওয়া জন্য এই ভিডিও", + "No Group with this key exists": "কোন গ্রুপ এই কী দিয়ে বিদ্যমান", + "No Monitor Found, Ignoring Request": "কোন মনিটর পাওয়া উপেক্ষা অনুরোধ", + "No Rotation": "কোন ঘূর্ণন", + "No such file": "কোন ধরনের ফাইল", + "NoMotionEmailText1": "কোন গতি জন্য", + "NoMotionEmailText2": "সেখানে এখন পর্যন্ত হয়েছে, কোন গতি সনাক্ত ক্যামেরা জন্য", + "NoVideosFoundForDateRange": "কোন ভিডিও পাওয়া যায়, এই তারিখ পরিসীমা. চেষ্টা সেটিং আরম্ভের তারিখ আরও ফিরে.", + "Not Authorized": "অনুমোদিত না", + "Not Connected": "সংযুক্ত নয়", + "Not Equal to": "সমান না", + "Not In": "না", + "Not Matches": "না, ম্যাচ", + "Not Permitted": "অনুমতি না", + "Not an Administrator Account": "না, একজন প্রশাসক অ্যাকাউন্ট", + "NotAuthorizedText1": "না, কঠিন জমা init কমান্ড দিয়ে \"প্রমাণীকরণ\",\"কে\" এবং \"uid\"", + "Notes": "নোট", + "NotesPlacholder": "মন্তব্য, আপনি ছেড়ে দিতে চান জন্য এই ক্যামেরা সেটিংস.", + "Number of Days to keep": "দিনের সংখ্যা রাখা", + "ONVIF": "ONVIF", + "ONVIF Scanner": "ONVIF স্ক্যানার", + "ONVIFnote": "আবিষ্কার ONVIF ডিভাইসের উপর নেটওয়ার্কের বাইরে আপনার নিজের অথবা এটি ফাঁকা ছেড়ে স্ক্যান করার জন্য আপনার বর্তমান নেটওয়ার্ক.
ব্যবহারকারীর নাম এবং পাসওয়ার্ড ফাঁকা রাখা যেতে পারে.", + "OpenCV Cascades": "OpenCV ক্যাসকেড", + "Order Streams": "যাতে স্ট্রিম", + "Output Method": "আউটপুট পদ্ধতি", + "Password": "পাসওয়ার্ড", + "Password Again": "আবার পাসওয়ার্ড", + "Passwords don't match": "পাসওয়ার্ড মেলে না", + "Paste JSON here.": "পেস্ট JSON আছেন.", + "Path": "পথ", + "Permissions": "অনুমতি", + "Points": "পয়েন্ট যোগ করার সময় পয়েন্ট উপর ক্লিক করুন ধারে বহুভুজ.", + "Port": "পোর্ট", + "Position X": "অবস্থান X", + "Position Y": "অবস্থান Y", + "Power Video Viewer": "পাওয়ার ভিডিও ভিউয়ার", + "Power Viewer": "ক্ষমতা ভিউয়ার", + "Preferences": "পছন্দ", + "Preset": "প্রিসেট", + "Probe Size": "প্রোব ফাইলের আকার", + "Process Crashed for Monitor": "প্রক্রিয়া ক্র্যাশ জন্য মনিটর", + "Process Unexpected Exit": "প্রক্রিয়া অপ্রত্যাশিত প্রস্থান", + "Profile": "প্রোফাইল", + "Quality": "মান 1 উচ্চ, 23 হয় কম", + "Query": "ক্যোয়ারী", + "RAM": "র্যাম", + "RTSP": "RTSP", + "RTSP Transport": "RTSP পরিবহন", + "Range or Single": "পরিসীমা বা একক", + "Rate": "হার (FPS যে)", + "Record": "রেকর্ড", + "Record File Type": "রেকর্ড ফাইল টাইপ", + "Record Height": "রেকর্ড উচ্চতা", + "Record Video Filter": "রেকর্ড ভিডিও ফিল্টার", + "Record Width": "রেকর্ড প্রস্থ", + "Recording": "রেকর্ডিং", + "Recording Flags": "রেকর্ডিং পতাকা", + "Recording Segment Interval": "রেকর্ডিং সেগমেন্ট ব্যবধান মিনিটের মধ্যে", + "Recording Timeout": "রেকর্ডিং সময়সীমার মধ্যে মিনিট", + "Recording Timestamp": "রেকর্ডিং টাইমস্ট্যাম্প", + "Recording Watermark": "রেকর্ডিং জলছাপ", + "RecordingText": "এটা বাঞ্ছনীয় যে আপনি সেট রেকর্ড ফাইল টাইপ করতে WebM, আছে MP4 , এবং ভিডিও কোডেক করতে libvpxকপি বা libx264 , কারণ আপনার ইনপুট টাইপ সেট করা হয় .", + "Refresh List of Cascades": "রিফ্রেশ তালিকা ক্যাসকেড", + "Region Editor": "অঞ্চল সম্পাদক", + "Region Name": "অঞ্চলের নাম", + "RegionNote": "পয়েন্ট হয় শুধুমাত্র সংরক্ষিত যখন আপনি টিপুন সংরক্ষণ করে মনিটর সেটিংস উইন্ডো.", + "Regions": "অঞ্চল", + "Remember Me": "আমাকে মনে রেখো", + "Reset Timer": "রিসেট টাইমার", + "Restarting Process": "পুনরায় আরম্ভ করার প্রক্রিয়া", + "Retry Connection": "পুনরায় সংযোগ সংখ্যা বার অনুমোদিত করতে ব্যর্থ", + "Retrying...": "Retrying...", + "Right": "সঠিক URL ঠিকানা", + "Right Stop": "ডান বন্ধ URL ঠিকানা", + "Rotate": "ঘোরান", + "Save": "সংরক্ষণ করুন", + "Save Directory": "ডিরেক্টরি সংরক্ষণ করুন", + "Save Events to SQL": "সংরক্ষণ ঘটনা এসকিউএল", + "Save Log in SQL": "সংরক্ষণ লগ ইন এসকিউএল এই পূরণ করতে পারেন, দ্রুত.", + "Save as": "হিসাবে সংরক্ষণ করুন", + "Saved Filters": "সংরক্ষিত ফিল্টার", + "Scan Settings": "স্ক্যান সেটিংস", + "Search": "অনুসন্ধান", + "Send Frames": "পাঠাতে ফ্রেম ধাক্কা ফ্রেম বিশ্লেষণ করা", + "Separate with commas, no spaces": "পৃথক কমা দিয়ে কোন স্পেস", + "Set to Watch Only": "সেট দেখতে শুধুমাত্র", + "Settings": "সেটিংস", + "Settings Changed": "সেটিংস পরিবর্তন", + "SettingsChangedText": "আপনার সেটিংস সংরক্ষণ করা হয়েছে এবং প্রয়োগ.", + "Shinobi": "Shinobi", + "Shinobi Streamer": "Shinobi উজ্জ্বল আলোকরশ্মি", + "Show Logs": "শো লগ", + "Silent": "নীরব", + "Simple": "সহজ", + "Size (mb)": "মাপ (মেগাবাইট)", + "Snapshot": "স্ন্যাপশট", + "Snapshot Flags": "স্ন্যাপশট পতাকা", + "Snapshots": "স্ন্যাপশট", + "Sort By": "দ্বারা বাছাই", + "Start": "শুরু", + "Start Recording": "রেকর্ডিং শুরু", + "Start Time": "সময় শুরু", + "Started": "শুরু", + "Status Indicator": "অবস্থা সূচক", + "Stop URL": "বন্ধ URL টি", + "Stream": "স্ট্রিম", + "Stream Flags": "স্ট্রিম পতাকা", + "Stream Timestamp": "স্ট্রিম টাইমস্ট্যাম্প", + "Stream Type": "প্রবাহ টাইপ,", + "Stream Watermark": "স্ট্রিম জলছাপ", + "Stream to YouTube": "স্ট্রিম YouTube", + "Stream to YouTube Flags": "স্ট্রিম করতে ইউটিউব পতাকা", + "StreamText": "

এই বিভাগে নামকরণ করা হবে এই প্রাথমিক স্ট্রিম আউট পদ্ধতি এবং এটি এর সেটিংস. এই স্ট্রিম প্রদর্শন করা হবে ড্যাশবোর্ড. আপনি ব্যবহার করতে পছন্দ HLS, কোন JPEG, বা MJPEG, তারপর আপনি গ্রাস করতে পারেন স্ট্রিম মাধ্যমে অন্যান্য প্রোগ্রাম.

ব্যবহার কোন JPEG স্ট্রিম মূলত বন্ধ করিয়া প্রাথমিক স্ট্রিম এবং ব্যবহার স্ন্যাপশট বিন পেতে ফ্রেম.

", + "Streamer": "উজ্জ্বল আলোকরশ্মি", + "Streams": "স্ট্রিম", + "Superuser": "Superuser", + "Switch on for Still Image": "সুইচ জন্য এখনও ইমেজ", + "TCP": "TCP", + "Text Box Color": "টেক্সট বক্স রঙ", + "Text Color": "টেক্সট রঙ", + "Time-lapse": "সময় ভ্রষ্টতা", + "Time-lapse Tool": "সময় ভ্রষ্টতা টুল", + "Timeout": "সময়সীমার", + "Timeout Reset on Next Motion": "সময়সীমার রিসেট পরবর্তী গতি", + "Toggle Sidebar": "টগল পার্শ্বদন্ডে", + "Top Left": "উপরের বাম", + "Top Right": "উপরের ডান", + "Trigger Record": "ট্রিগার রেকর্ড", + "Trigger Successful": "ট্রিগার সফল", + "UDP": "এর ফলে UDP", + "URL": "URL টি", + "URL Stop Timeout": "URL বন্ধ সময়সীমার চালানো বন্ধ URL পরে এক্স মিলিসেকেন্ড", + "US": "আমাদের", + "Unable to Launch": "আরম্ভ করতে অক্ষম", + "UnabletoLaunchText": "সংরক্ষণ করুন, নতুন মনিটর প্রথম. তারপর চেষ্টা করতে আরম্ভ অঞ্চলের সম্পাদক.", + "Up": "আপ URL ঠিকানা", + "Up Stop": "আপ বন্ধ URL ঠিকানা", + "Username": "ব্যবহারকারীর নাম", + "Value": "মান", + "Video": "ভিডিও", + "Video Codec": "ভিডিও কোডেক", + "Video Filter": "ভিডিও ফিল্টার", + "Video Finished": "ভিডিও সমাপ্ত", + "Video Length (minutes) and Motion Count per video": "ভিডিও দৈর্ঘ্য (মিনিট) এবং গতি গণনা প্রতি ভিডিও", + "Video Record Rate": "ভিডিও রেকর্ড হার (FPS যে)", + "Video Status": "ভিডিও অবস্থা", + "Video and Time Span (Minutes)": "ভিডিও এবং সময় স্প্যান (মিনিট)", + "Videos": "ভিডিও", + "Videos List": "ভিডিও তালিকা", + "Watch": "ওয়াচ", + "Watch Only": "ওয়াচ শুধুমাত্র", + "WebDAV": "অম্রো", + "WebM (libvpx)": "WebM (libvpx)", + "Webdav Error": "অম্রো ত্রুটি", + "WebdavErrorText": "উদ্ধার করতে পারে না. আপনি কি করতে ক্যামেরা ফোল্ডার ভিতরে আপনার নির্বাচিত ডিরেক্টরি সংরক্ষণ করুন?", + "Webhook": "Webhook", + "Webhook URL": "Webhook URL টি", + "Width": "প্রস্থ", + "Yes": "হ্যাঁ", + "Zoom In": "জুম ইন URL ঠিকানা", + "Zoom In Stop": "জুম বন্ধ URL ঠিকানা", + "Zoom Out": "জুম আউট URL ঠিকানা", + "Zoom Out Stop": "জুম আউট বন্ধ URL ঠিকানা", + "a day": "একটি দিন", + "a few seconds": "কয়েক সেকেন্ড", + "a minute": "একটি মিনিট", + "a month": "একটি মাস", + "a year": "একটি বছর", + "aac": "এএসি", + "aac (Default)": "এএসি (ডিফল্ট)", + "ac3": "ac3", + "ago": "আগে", + "an hour": "একটি ঘন্টা", + "blankPassword": "ছেড়ে ফাঁকা রাখা একই পাসওয়ার্ড", + "calendar": "ক্যালেন্ডার", + "clientStreamFailedattemptingReconnect": "ক্লায়েন্ট সাইড ctream পরীক্ষা ব্যর্থ প্রয়াস পুনরায় সংযোগ স্থাপন.", + "confirmDeleteFilter": "আপনি চাই প্রতি মুছে ফেলা এই ফিল্টার? আপনি পুনরুদ্ধার করা সম্ভব না, এটা.", + "copy": "কপি", + "days": "দিন", + "dropBoxSuccess": "সাফল্য! ফাইল সংরক্ষণ করার জন্য আপনার ড্রপবক্স.", + "for Global Access": "গ্লোবাল এক্সেস", + "hours": "ঘন্টা", + "in": "এ", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis (ডিফল্ট)", + "libvpx (Default)": "libvpx (ডিফল্ট)", + "libvpx-vp9": "libvpx-vp9", + "libx264": "libx264", + "libx264 (Default)": "libx264 (ডিফল্ট)", + "libx265": "libx265", + "minutes": "মিনিট", + "modifyVideoText1": "পদ্ধতি বিদ্যমান নেই. পরীক্ষা নিশ্চিত করুন যে আপনি সর্বশেষ মান URL টি নয়, ফাঁকা.", + "monitorEditFailedMaxReached": "আপনার অ্যাকাউন্ট পৌঁছেছে সর্বোচ্চ সংখ্যা, যে ক্যামেরা তৈরি করা যেতে পারে. কথা বলতে একজন প্রশাসক যদি আপনি চান এই পরিবর্তন.", + "monitorEditText1": "অবৈধ তথ্য পরীক্ষা করে দেখুন, এই একটি বৈধ আমদানি স্ট্রিং.", + "monitorEditText2": "অবৈধ বিবরণ স্ট্রিং. দেখতে পরীক্ষা করুন, এটি একটি JSON স্ট্রিং এবং না একটি নিয়মিত বস্তুর অতিক্রান্ত হচ্ছে.", + "monitorGetText1": "অসম্পূর্ণ অনুরোধ অপসারণ, গত স্ল্যাশ মধ্যে URL বা করা গ্রহণযোগ্য মান.", + "months": "মাস", + "noSpecialCharacters": "কোন স্পেস বা বিশেষ অক্ষর.", + "on": "উপর", + "on Error": "উপর ত্রুটি", + "startUpText0": "আকার জন্য পরীক্ষা করে দেখুন ভিডিও", + "startUpText1": "শেষে আকার জন্য পরীক্ষা করে দেখুন ভিডিও", + "startUpText2": "সব ব্যবহারকারীদের চেক অপেক্ষা করুন, বন্ধ করতে, খোলা ফাইল এবং ফাইল মুছে ফেলুন উপর ব্যবহারকারী সীমা", + "startUpText3": "অপেক্ষা করতে দিতে অসমাপ্ত ভিডিও পরীক্ষা কিছু সময়. 3 সেকেন্ড.", + "startUpText4": "শুরু, সব মনিটর সেট দেখতে এবং রেকর্ড", + "startUpText5": "Shinobi প্রস্তুত হয়.", + "superAdminText": "\"সুপার.json\" বিদ্যমান নয়. দয়া করে নামান্তর \"সুপার.নমুনা.json\", \"সুপার.json\".", + "superAdminTitle": "Shinobi : সুপার অ্যাডমিন", + "total": "মোট", + "updateKeyText1": "\"updateKey\" থেকে অনুপস্থিত, \"conf.json\", আপডেট করতে পারবেন না এই ভাবে যতক্ষণ না আপনি এটি যোগ করুন.", + "updateKeyText2": "\"updateKey\" ভুল হয়.", + "years": "বছর" +} diff --git a/languages/de.json b/languages/de.json new file mode 100644 index 0000000..185ec88 --- /dev/null +++ b/languages/de.json @@ -0,0 +1,497 @@ +{ + "\"No Motion\" Detector": "Detektor für \"keine Bewegung\"", + "# of Allow MJPEG Clients": "Max. Anz. von MJPEG-Clients 0 = unbeschränkt", + "180 Degrees": "180 Grad", + "2-Factor Authentication": "2-Faktor-Authentifizierung", + "90 Clockwise": "90° im Uhrzeigersinn", + "90 Clockwise and Vertical Flip": "90° im Uhrzeigersinn drehen und vertikal spiegeln", + "90 Counter Clockwise and Vertical Flip (default)": "90° entgegen dem Uhrzeigersinn drehen und vertikal spiegeln (Standard)", + "API": "API", + "API Key Added": "API-Schlüssel hinzugefügt", + "API Key Deleted": "API-Schlüssel gelöscht", + "API Keys": "API-Schlüssel", + "APIKeyAddedText": "Sie können diesen API-Schlüssel nun verwenden.", + "APIKeyDeletedText": "Der API-Schlüssel wurde gelöscht. Er wird nicht mehr funktionieren.", + "ASC": "Auf", + "Account Info": "Account-Info", + "AccountEditText1": "Ändern nicht möglich. Bitte die Seite neu laden, falls das Problem weiterhin besteht.", + "Accounts": "Konten", + "Action for Selected": "Aktion für Ausgewählte", + "Add": "Hinzufügen", + "Add Monitor": "Monitor Hinzufügen", + "Add New": "Neu hinzufügen", + "Admin": "Admin", + "Advanced": "Experten", + "Again": "Erneut", + "All Monitors": "Alle Monitore", + "All Monitors and Privileges": "Alle Monitore und Privilegien", + "All Warnings": "Alle Warnungen", + "Allow Next Command": "Min. Zeitspanne zwischen zwei Befehlenin Minuten", + "Allow Next Email": "Min. Zeitspanne zwischen zwei E-Mailsin Minuten", + "Allow Next Trigger": "Min. Zeitspanne zwischen zwei Triggernin Millisekunden", + "Allowed IPs": "Erlaubte IPs", + "Analyzation Duration": "Analyse-Dauer", + "Archive": "Archiv", + "Audio Codec": "Audio-Codec", + "Authenticate": "Authentifizieren", + "Auto": "Auto", + "Autosave": "Autom. Speichern", + "Base64 over Websocket": "Base64 über Websocket", + "Bottom Left": "Unten links", + "Bottom Right": "Unten rechts", + "Browser Console Log": "Browser-Konsole", + "CPU": "CPU", + "CPU indicator will not work. Continuing...": "Die CPU-Anzeige funktioniert nicht. Weiter...", + "CSS": "CSS - Definiert eigene Styles im Dashboard", + "Calendar": "Kalender", + "Camera Password": "Kamera-Passwort", + "Camera Username": "Kamera-Benutzername", + "Camera is not recording": "Die Kamera nimmt nicht auf.", + "CameraNotRecordingText": "Die Einstellungen sind möglicherweise nicht kompatibel. Bitte die Encoder-Einstellung überprüfen.", + "Can Control Monitors": "Darf Monitore steuern", + "Can Delete Videos": "Darf Videos löschen", + "Can Delete Videos and Events": "Darf Videos und Events löschen", + "Can Edit Monitor": "Darf Monitor-Einstellungen bearbeiten", + "Can Get Logs": "Darf die Logs sehen", + "Can Get Monitors": "Darf Monitore auflisten", + "Can View Monitor": "Darf Monitore sehen", + "Can View Snapshots": "Darf Snapshots erstellen/sehen", + "Can View Streams": "Darf Streams sehen", + "Can View Videos": "Darf Videos anschauen", + "Can View Videos and Events": "Darf Videos und Events ansehen", + "Can't Connect": "Konnte nicht Verbinden.", + "Center": "Mitte - URL-Adresse", + "Chat on Discord": "Chat auf Discord", + "Check": "Überprüfen", + "Check Signal Interval": "Signal-Überprüfungsintervall in Minuten", + "Check for Motion First": "Bewegungserkennung zuerst", + "Close": "Schließen", + "Closed": "Geschlossen", + "Command": "Befehl", + "Command on Trigger": "Befehl beim Trigger", + "Complete Stream URL": "Komplette Stream-URL", + "Confirm": "Bestätigen", + "Connected": "Verbunden", + "Connection Type": "Verbindungstyp", + "Control": "Steuerung", + "Control Error": "Steuerungsfehler", + "ControlErrorText1": "Die Steuerung ist nicht aktiviert", + "Controllable": "Steuerbar", + "Country of Plates": "Kennzeichen-Land", + "Counts of Motion": "Bewegungsschwelle", + "Current": "Aktuell", + "Currently viewing": "Anzahl Beobachter", + "Custom": "Benutzerdefiniert", + "Custom Base URL": "Eigene Basis-URL leer Lassen, um Host-URL zu verwenden", + "DB Lost.. Retrying..": "Datenbank-Verbindung verloren... Erneuter Versuch...", + "DESC": "Ab", + "Dashboard": "Dashboard", + "Dashboard Language": "Dashboard-Sprache", + "Dashcam": "Dashcam", + "Dashcam (Streamer v2)": "Dashcam (Streamer v2)", + "Date Range": "Datumsbereich", + "Debug": "Debug", + "Default": "Standard", + "Delete": "Löschen", + "Delete Filter": "Filter Löschen", + "Delete Matches": "Lösche Treffer", + "Delete Monitor": "Lösche Monitor", + "Delete Motionless Video": "Videos ohne Bewegung löschen", + "Delete Motionless Videos (Record)": "Videos ohne Bewegung löschen (Aufzeichnung)", + "Delete Selected Videos": "Ausgewählte Videos löschen", + "Delete Video": "Video Löschen", + "Delete selected": "Ausgewählte löschen", + "DeleteMonitorText": "Möchten Sie diesen Monitor wirklich löschen? Sie können diese Löschung nicht mehr rückgängig machen. Die Dateien für diese Monitor-ID verbleiben im Dateisystem. Wenn Sie einen Monitor mit der gleichen ID erstellen, werden die Videos und Ereignisse wieder sichtbar.", + "DeleteSelectedVideosMsg": "Wollen Sie diese Videos löschen? Sie können diese Löschung nicht mehr rückgängig machen.", + "DeleteVideoMsg": "Wollen Sie dieses Video löschen? Sie können diese Löschung nicht mehr rückgängig machen.", + "Deleted": "Gelöscht", + "Detect Objects": "Erkennung von Objekten Siehe unten", + "Detector": "Detektor", + "Detector Flags": "Detektor-Flags", + "Detector Rate": "Detektor-Rate (Bilder pro Sekunde)", + "DetectorText": "

Die Detektor-Bildgröße sollte auf 640x480 oder kleiner eingestellt werden.. Dies optimiert die Geschwindigkeit beim Auslesen der Bilder.

", + "Disable Night Vision": "Nachtsicht deaktivieren URL-Adresse", + "Disable Nightvision": "Nachtsicht deaktivieren", + "Disabled": "Deaktiviert", + "Documentation": "Dokumentation", + "Don't show this anymore": "Nicht erneut anzeigen", + "Double Quote Directory": "Verzeichnisse doppelt quoten Z.B. bei Verzeichnissen mit Leerzeichen sinnvoll, da es bei diesen zu Abstürzen kommen kann.", + "Down": "Nach unten URL-Adresse", + "Down Stop": "Nach unten-Stopp URL-Adresse", + "Download": "Download", + "EU": "EU", + "Edit": "Bearbeiten", + "Email": "E-Mail", + "Email Details": "E-Mail-Details", + "Email on No Motion": "E-Mail bei \"Keine Bewegung\"", + "Email on Trigger": "E-Mail beim Trigger - E-Mails werden an dem Haupt-Account-Inhaber geschickt.", + "Enable Night Vision": "Nachtsicht aktivieren - URL-Adresse", + "Enable Nightvision": "Nachtsicht aktivieren", + "Enabled": "Aktiviert", + "End": "Ende", + "End Time": "Endzeit", + "Ended": "Beendet", + "Enlarge": "Vergrößern", + "Enter this code to proceed": "Geben Sie bitte diesen Code ein um fortzufahren.", + "Equal to": "Gleich", + "Error Connecting": "Fehler bei der Verbindung", + "Event": "Ereignis", + "Event Limit": "Max. Anzahl der Ereignisse", + "EventText1": "Ein Bewegungsereignis wurde ausgelöst.", + "EventText2": "Konnte die E-Mail nicht versenden, der Zugriff auf die Datei war nicht möglich.", + "Events": "Ereignisse", + "Example": "Beispiel", + "Execute Command": "Befehl ausführen", + "Executed": "Ausgeführt", + "Export": "Export", + "FFmpegCantStart": "Der FFmpeg-Prozess konnte nicht gestartet werden.", + "FFmpegCantStartText": "Die Recording-Engine (FFmpeg) für diese Kamera konnte nicht gestartet werden. Möglicherweise ist die Kamera-Konfiguration falsch. Bitte in den Logs nachschauen und diese ggf. in Issues auf Github veröffentlichen.", + "FFmpegTip": "FFprobe ist ein Multimedia-Stream-Analyser. Sie können es verwenden, um Informationen über den Streamtyp, -Dauer, -Bildrate, -Bildgröße, usw. zu erhalten.", + "FFprobe": "FFprobe", + "FactorAuthText1": "Diese Code ist 15 Minuten aktiv. Nach der Anmeldung, wird der Timer für den gleichen Code um weitere 15 Minuten verlängert.", + "Fatal": "Fatal", + "Fatal Maximum Reached": "Max. Verbindungsversuche erreicht, die Kamera wird gestoppt.", + "FatalMaximumReachedText": "Max. Verbindungsversuche erreicht.", + "Feed-in Image Height": "Feed-in-Bildhöhe", + "Feed-in Image Width": "Feed-in-Bildbreite", + "Fields cannot be empty": "Die Felder dürfen nicht leer sein.", + "File Not Exist": "Datei nicht vorhanden.", + "File Not Found": "Datei nicht gefunden.", + "File Type": "Dateityp", + "FileNotExistText": "Die Datei konnte nicht gespeichert werden, die Datei existiert nicht mehr.", + "Filename": "Dateiname", + "Filesize": "Dateigröße", + "Filter ID": "Filter-ID", + "Filter Matches": "Filter-Bedingung", + "Filter Name": "Filter-Name", + "FilterMatchesText1": "Die Filter-Bedingung war erfüllt.", + "FilterMatchesText2": "Videos gefunden.", + "Filters": "Filter", + "Filters Updated": "Filter aktualisiert", + "FiltersUpdatedText": "Ihre Änderungen wurden gespeichert und angewendet.", + "Find Where": "Suchort", + "Fix": "Reparieren", + "Fix Video": "Video reparieren", + "FixVideoMsg": "Dieses Video reparieren? Diese Aktion kann nicht rückgängig gemacht werden.", + "Font Path": "Schrift-Pfad", + "Font Size": "Schriftgröße", + "Force Port": "Port forcieren", + "Found Devices": "Gefundene Geräte", + "Frame Rate": "Bildrate (Bilder pro Sekunde)", + "Full Frame Detection": "Vollbilder erkennen", + "Fullscreen": "Vollbild", + "Greater Than": "Größer als", + "Greater Than or Equal to": "Größer als oder gleich", + "Group Key": "Gruppen-Schlüssel", + "Group Name": "Gruppenname", + "Grouping": "Gruppierung ", + "H.264 / H.265 / H.265+": "H.264 / H.265 / H.265+", + "HLS (.m3u8)": "HLS - (.m3u8)", + "HLS (includes Audio)": "HLS (mit Audio)", + "HLS Audio Encoder": "HLS-Audio-Encoder", + "HLS List Size": "HLS-Listen-Größe", + "HLS Preset": "HLS-Preset", + "HLS Segment Length": "HLS-Segment-Länge in Sekunden", + "HLS Video Encoder": "HLS-Video-Encoder", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "Height": "Höhe", + "Help": "Hilfe", + "Hide List": "Liste ausblenden", + "Hide Notes": "Meldungen auszublenden", + "Host": "Host", + "Hotswap Modes (Watch-Only)": "Hotswap-Mode (Betrachtungsmodus)", + "How to Record": "Aufnahmeart", + "IP Address": "IP-Adresse", + "Identity": "Identität", + "IdentityText1": "Mit dieser ID wird ein Monitor eindeutig identifiziert. Sie können es nicht nachträglich ändern. Tipp: Verwenden Sie für die Monitor-ID eine für Menschen gut lesbare Bezeichnung, z.B. Parkplatz.", + "IdentityText2": "Sie können einen Monitor dadurch duplizieren (klonen), indem Sie die Monitor-ID ändern und anschließend speichern. Wenn Sie hingegen eine bereits vorhandene Monitor-ID verwenden, wird der entsprechende Monitor überschrieben.", + "Idle": "Im Leerlauf", + "Image Height": "Bildhöhe", + "Image Location": "Bild-Pfad Absoluter Pfad, oder leer lassen, um die globale Einstellung zu übernehmen", + "Image Position": "Bild-Position", + "Image Width": "Bildbreite", + "Import": "Import", + "Import Monitor Configuration": "Monitor-Konfiguration importieren", + "ImportMonitorConfigurationText": "Dadurch werden nicht gespeicherte änderungen überschrieben. Importierte Änderungen werden nur dann angewendet, wenn Sie Speichern drücken.", + "In": "In", + "Incorrect Settings Chosen": "Falsche Einstellungen gewählt", + "Indifference": "Erkennungsschwelle", + "Input": "Eingang", + "Input Flags": "Eingang-Flags", + "Input Type": "Input-Typ", + "InputText1": "Hier wird festgelegt, wie der Kamera-Stream verarbeitet wird. Für eine optimale Leistung, müssen manchmal die internen Kamera-Einstellungen angepasst werden. Die Kamera kann auch über den eingebauten ONVIF-Scanner gefunden werden. Einige ONVIF-Kameras müssen im dazu Vorfeld mit einem Hersteller-Tool angepasst werden. Hilfreiches Tool: ONVIF Device Manager für Windows.", + "InputText2": "
  • Bildrate (Bilder pro Sekunde) : Hoch : 10-15 B/s, Niedrig : 2-5 B/s
  • I-frame-Interval : 80
  • Bit-Raten-Typ : CBR (Konstante Bitrate)
  • Bitrate : zwischen 256 Kbps - 500 Kbps
", + "InputText3": "Wenn Sie Hilfe bei der Bestimmung der Kamera-Parameter benötigen, werfen Sie einen Blick auf die Kamera-URL-Liste auf der Shinobi-Website.", + "Invalid JSON": "Ungültiges JSON-Fragment", + "InvalidJSONText": "Bitte sicherstellen, dass ein Gültiger JSON-Fragment mit der Shinobi-Monitor-Konfiguration benutzt wird.", + "JPEG": "JPEG", + "JPEG (Auto Enables JPEG API)": "JPEG (aktiviert die JPEG-API)", + "JPEG API": "JPEG-API - Snapshot (cgi-bin)", + "JPEG Error": "JPEG-Fehler", + "JPEG Mode": "Im JPEG-Modus", + "JPEGErrorText": "Ein Fehler beim Abrufen der Kamera-Daten ist aufgetreten.", + "Leave blank for random.": "Leer lassen für einen zufälligen Wert.", + "Left": "Nach links URL-Adresse", + "Left Stop": "Nach links-Stopp URL-Adresse", + "Less Than": "Weniger als", + "Less Than or Equal to": "Weniger als oder gleich", + "Like": "Wie", + "Lisence Plate Detector": "Kfz-Kennzeichen-Detektor", + "List Toggle": "Liste umschalten", + "Live Stream Toggle": "Live-Stream umschalten", + "Live View": "Live-Ansicht", + "Local": "Lokal", + "Log Level": "Log-Level", + "Log Signal Event": "Logge Signal-Ereignisse nur Client-Seite", + "Logging": "Logging", + "Login": "Login", + "Logout": "Logout", + "Logs": "Logs", + "MB": "MB", + "MJPEG": "MJPEG", + "MP4 (copy, libx264, libx265)": "MP4 (kopieren, libx264, libx265)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)", + "MailError": "E-Mail-Fehler: Es Konnte keine E-Mail versendet werden. Bitte die conf.json überprüfen. Alle E-Mail-Funktionen werden vorübergehend deaktiviert.", + "Matches": "Trifft zu", + "Max Storage Amount": "Max Speichermenge in MB", + "Mode": "Modus", + "Monitor": "Monitor", + "Monitor Added by user": "Monitor durch Benutzer hinzugefügt.", + "Monitor Capture Rate": "Monitor Bildrate (Bilder pro Sekunde)", + "Monitor Groups": "Monitor-Gruppen", + "Monitor ID": "Monitor-ID", + "Monitor Idling": "Monitor im Leerlauf", + "Monitor Name": "Monitor Name", + "Monitor Settings": "Monitor-Einstellungen", + "Monitor Stopped": "Monitor gestoppt", + "Monitor Updated by user": "Monitor durch den Benutzer aktualisiert.", + "Monitor mode changed": "Monitor-Modus geändert", + "Monitor mode is already": "Monitor-Modus ist bereits", + "Monitor or Key does not exist.": "Monitor oder Schlüssel nicht vorhanden.", + "MonitorIdlingText": "Der Monitor wurde in den Leerlauf geschaltet.", + "MonitorStoppedText": "Der Monitor wurde gestoppt.", + "Monitors": "Monitore", + "Monitors per row": "Monitore pro Zeile in der Montage-Ansicht", + "Montage": "Montage", + "Motion GUI": "Motion-GUI", + "Motion Meter": "Bewegungsindikator", + "Name": "Name", + "No": "Keine", + "No Audio": "Kein Audio", + "No Data": "Keine Daten", + "No Events found for this video": "Keine Ereignisse für dieses Video gefunden.", + "No Group with this key exists": "Keine Gruppe mit diesem Schlüssel vorhanden.", + "No Monitor Found, Ignoring Request": "Kein Monitor gefunden, ignoriere Anfrage.", + "No Rotation": "Keine Rotation", + "No such file": "Keine solche Datei", + "NoMotionEmailText1": "Keine Bewegung", + "NoMotionEmailText2": "Es wurden keine Bewegungen für die Kamera erkannt für", + "NoVideosFoundForDateRange": "Keine Videos in diesem Zeitraum gefunden. Eventuell das Start-Datum weiter zurück stellen.", + "Not Authorized": "Nicht autorisiert", + "Not Connected": "Nicht verbunden", + "Not Equal to": "Ungleich", + "Not In": "Nicht in", + "Not Matches": "Trifft nicht zu", + "Not Permitted": "Nicht erlaubt", + "Not an Administrator Account": "Kein Administrator-Konto", + "NotAuthorizedText1": "Sie sind nicht berechtigt, init-Befehle mit \"auth\",\"ke\" und \"uid\" zu senden.", + "Notes": "Hinweise", + "NotesPlacholder": "Ihre Kommentare zu diesen Kamera-Einstellungen", + "Number of Days to keep": "Für die Anzahl von Tagen behalten", + "ONVIF": "ONVIF", + "ONVIF Scanner": "ONVIF-Scanner", + "ONVIFnote": "Leer lassen, um ONVIF-Geräte im eigenen Netzwerk zu suchen. Netzwerk spezifizieren, für Suchen außerhalb des eigenen Netzwerks.
Benutzername und Kennwort können leer gelassen werden.", + "OpenCV Cascades": "OpenCV-Kaskaden", + "Order Streams": "Streams ordnen", + "Output Method": "Ausgabe-Methode", + "Password": "Passwort", + "Password Again": "Passwort (Wiederh.)", + "Passwords don't match": "Die Passwörter stimmen nicht überein.", + "Paste JSON here.": "Fügen Sie hier ein JSON-Fragment ein.", + "Path": "Pfad", + "Permissions": "Berechtigungen", + "Points": "Punkte Um weitere Punkte hinzuzufügen, klicken Sie bitte auf den Rand des Polygons.", + "Port": "Port", + "Position X": "Position X", + "Position Y": "Position Y", + "Power Video Viewer": "Power-Video-Viewer", + "Power Viewer": "Power-Viewer", + "Preferences": "Einstellungen", + "Preset": "Voreinstellung", + "Probe Size": "Probe-Größe", + "Process Crashed for Monitor": "Der Prozess für den Monitor ist abgestürzt", + "Process Unexpected Exit": "Der Prozess wurde unerwartet beendet.", + "Profile": "Profil", + "Quality": "Qualität 1 = hoch, 23 = gering", + "Query": "Query", + "RAM": "RAM", + "RTSP": "RTSP", + "RTSP Transport": "RTSP-Transport", + "Range or Single": "Bereich oder Einzeln", + "Rate": "Bildrate (Bilder pro Sekunde)", + "Record": "Aufnahme", + "Record File Type": "Datei-Typ (Aufnahme)", + "Record Height": "Bidhöhe (Aufnahme)", + "Record Video Filter": "Video-Filter (Aufnahme)", + "Record Width": "Bildbreite (Aufnahme)", + "Recording": "Aufnahme", + "Recording Flags": "Aufnahme-Flags", + "Recording Segment Interval": "Aufnahme-Dauer pro Segment in Minuten", + "Recording Timeout": "Aufnahme-Timeout in Minuten", + "Recording Timestamp": "Aufnahme-Zeitstempel", + "Recording Watermark": "Aufnahme-Wasserzeichen", + "RecordingText": "", + "Refresh List of Cascades": "Liste der Kaskaden einlesen", + "Region Editor": "Region-Editor", + "Region Name": "Name der Region", + "RegionNote": "Die hier definierten Punkte werden erst dann gespeichert, wenn Sie auf Speichern im Fenster Monitor-Einstellungen klicken.", + "Regions": "Regionen", + "Remember Me": "Merken", + "Reset Timer": "Reset-Timer", + "Restarting Process": "Der Prozess wird neu gestartet.", + "Retry Connection": "Verbindungsversuche Maximale Anzahl von Verbindungsversuchen. 0 = unendlich", + "Retrying...": "Erneuter Versuch...", + "Right": "Nach rechts URL-Adresse", + "Right Stop": "Nach rechts-Stopp URL-Adresse", + "Rotate": "Drehen", + "Save": "Speichern", + "Save Directory": "Verzeichnis Speichern", + "Save Events to SQL": "Ereignisse in der Datenbank speichern", + "Save Log in SQL": "Log in der Datenbank speichernAchtung: Die Datenbank kann dabei sehr schnell groß werden.", + "Save as": "Speichern als", + "Saved Filters": "Gespeicherte Filter", + "Scan Settings": "Scan-Einstellungen", + "Search": "Suche", + "Send Frames": "Bilddaten zum Detektor senden Bilddaten werden analysiert", + "Separate with commas, no spaces": "Getrennt mit Kommas, ohne Leerzeichen", + "Set to Watch Only": "Aufnahme beenden", + "Settings": "Einstellungen", + "Settings Changed": "Einstellungen geändert", + "SettingsChangedText": "Die Einstellungen wurden gespeichert und angewendet.", + "Shinobi": "Shinobi", + "Shinobi Streamer": "Shinobi-Streamer", + "Show Logs": "Logs anzeigen", + "Silent": "Still", + "Simple": "Einfach", + "Size (mb)": "Größe (MB)", + "Snapshot": "Snapshot", + "Snapshot Flags": "Snapshot-Flags", + "Snapshots": "Snapshots", + "Sort By": "Sortieren nach", + "Start": "Starten", + "Start Recording": "Aufnahme starten", + "Start Time": "Startzeit", + "Started": "Gestartet", + "Status Indicator": "Statusanzeige", + "Stop URL": "Stop-URL", + "Stream": "Stream", + "Stream Flags": "Stream-Flags", + "Stream Timestamp": "Stream-Timestamp", + "Stream Type": "Stream-Typ", + "Stream Watermark": "Stream-Wasserzeichen", + "Stream to YouTube": "Stream zu YouTube schicken", + "Stream to YouTube Flags": "YouTube-Flags", + "StreamText": "

Dieser Abschnitt legt die primäre Stream-Methode und ihre Einstellungen fest. Dieser Stream wird im Dashboard angezeigt. Wenn Sie HLS, JPEG oder MJPEG verwenden, können Sie den Stream durch andere Programme nutzen.

Beim JPEG-Stream wird der primäre Stream abgeschaltet und stattdessen den Snapshot-Modus verwendet.

", + "Streamer": "Streamer", + "Streams": "Streams", + "Superuser": "Superuser", + "Switch on for Still Image": "Schalter für Standbild", + "TCP": "TCP", + "Text Box Color": "Textbox-Farbe", + "Text Color": "Textfarbe", + "Time-lapse": "Zeitraffer", + "Time-lapse Tool": "Zeitraffer-Werkzeug", + "Timeout": "Timeout", + "Timeout Reset on Next Motion": "Timeout-Zähler bei nächster Bewegung zurücksetzen", + "Toggle Sidebar": "Sidebar umschalten", + "Top Left": "Oben links", + "Top Right": "Oben rechts", + "Trigger Record": "Aufzeichnung triggern", + "Trigger Successful": "Trigger erfolgreich", + "UDP": "UDP", + "URL": "URL", + "URL Stop Timeout": "Stopp-URL-Timeout Ruft die Stopp-URL nach X Millisekunden auf", + "US": "US", + "Unable to Launch": "Konnte nicht starten", + "UnabletoLaunchText": "Bitte speichern Sie zuerst die neuen Monitor-Einstellungen. Danach steht der Region-Editor zur Verfügung.", + "Up": "Nach oben URL-Adresse", + "Up Stop": "Nach oben-Stopp URL-Adresse", + "Username": "Benutzername", + "Value": "Wert", + "Video": "Video", + "Video Codec": "Video-Codec", + "Video Filter": "Video-Filter", + "Video Finished": "Das Video ist fertig.", + "Video Length (minutes) and Motion Count per video": "Video-Länge (in Minuten) und Bewegungsanzahl pro video", + "Video Record Rate": "Video-Aufnahme-Rate (Bilder pro Sekunde)", + "Video Status": "Video-Status", + "Video and Time Span (Minutes)": "Video und Zeitspanne (in Minuten)", + "Videos": "Videos", + "Videos List": "Video-Liste", + "Watch": "Anschauen", + "Watch Only": "Nur Anschauen", + "WebDAV": "WebDAV", + "WebM (libvpx)": "WebM (libvpx)", + "Webdav Error": "WebDAV-Fehler", + "WebdavErrorText": "Kann nicht speichern. Bitte überprüfen, ob die Kamera-Ordner im gewählten Verzeichnis angelegt sind.", + "Webhook": "Webhook", + "Webhook URL": "Webhook-URL", + "Width": "Breite", + "Yes": "Ja", + "Zoom In": "Zoom-In URL-Adresse", + "Zoom In Stop": "Zoom-In Stopp URL-Adresse", + "Zoom Out": "Zoom-Out URL-Adresse", + "Zoom Out Stop": "Zoom-Out Stopp URL-Adresse", + "a day": "einen Tag", + "a few seconds": "ein paar Sekunden", + "a minute": "eine Minute", + "a month": "einen Monat", + "a year": "ein Jahr", + "aac": "aac", + "aac (Default)": "aac (Standard)", + "ac3": "ac3", + "ago": "vor", + "an hour": "eine Stunde", + "blankPassword": "Leer lassen, um das gleiche Passwort zu verwenden.", + "calendar": "Kalender", + "clientStreamFailedattemptingReconnect": "Client-seitiger Stream-Check fehlgeschlagen. Erneuter Versuch...", + "confirmDeleteFilter": "Wollen Sie diesen Filter wirklich löschen? Sie können ihn nicht mehr wiederherstellen.", + "copy": "kopieren", + "days": "Tage", + "dropBoxSuccess": "Die Dateien wurden erfolgreich in der Dropbox gespeichert.", + "for Global Access": "Für den weltweiten Zugriff", + "hours": "Stunden", + "in": "in", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis (Standard)", + "libvpx (Default)": "libvpx (Standard)", + "libvpx-vp9": "libvpx-vp9", + "libx264": "libx264", + "libx264 (Default)": "libx264 (Standard)", + "libx265": "libx265", + "minutes": "Minuten", + "modifyVideoText1": "Die Methode ist nicht vorhanden. Bitte sicherstellen, dass der letzte Wert der URL nicht leer ist.", + "monitorEditFailedMaxReached": "Die maximale Anzahl von Kameras wurde erreicht. Zum Erhöhen des Wertes wenden Sie sich an Ihren Administrator.", + "monitorEditText1": "Ungültige Daten. Bitte einen gültigen Import-String eingeben.", + "monitorEditText2": "Ungültiger Details-String. Bitte einen gültigen JSON-String eingeben.", + "monitorGetText1": "Unvollständiger Request. Entweder den Schrägstrich am Ende entfernen oder einen gültigen Wert setzen.", + "months": "Monate", + "noSpecialCharacters": "Es dürfen keine Leerzeichen oder Sonderzeichen enthalten sein.", + "on": "auf", + "on Error": "bei Fehlern", + "startUpText0": "Größe der Videos überprüfen", + "startUpText1": "Größe der Videos überprüft", + "startUpText2": "Alle Benutzer überprüft. Bitte warten, geöffnete Dateien werden geschlossen und Dateien über Benutzer-Limit werden entfernt.", + "startUpText3": "Warte weitere 3 Sekunden auf den Abschluss der Überprüfung.", + "startUpText4": "Starte alle Monitore.", + "startUpText5": "Shinobi ist bereit.", + "superAdminText": "\"super.json\" ist nicht vorhanden. Die Datei \"super.Probe.json\" kann als Vorlage für \"super.json\" verwendet werden.", + "superAdminTitle": "Shinobi : Super Admin", + "total": "insgesamt", + "undefined": "nicht definiert", + "updateKeyText1": "Kein \"updateKey\" in \"conf.json\" vorhanden. Es werden keine Updates durchgeführt.", + "updateKeyText2": "\"updateKey\" ist falsch.", + "years": "Jahre" +} diff --git a/languages/en_CA.json b/languages/en_CA.json new file mode 100644 index 0000000..5fed55e --- /dev/null +++ b/languages/en_CA.json @@ -0,0 +1,695 @@ +{ + "Shinobi": "Shinobi", + "superAdminTitle": "Shinobi : Super Admin", + "Login": "Login", + "Authenticate": "Authenticate", + "Dashboard": "Dashboard", + "Streamer": "Streamer", + "Admin": "Admin", + "Superuser": "Superuser", + "Dashcam": "Dashcam", + "Email": "Email", + "Username": "Username", + "Profile": "Profile", + "Password": "Password", + "Password Again": "Password Again", + "Remember Me": "Remember Me", + "RAM": "RAM", + "CPU": "CPU", + "on": "on", + "Power Viewer": "Power Viewer", + "Power Video Viewer": "Power Video Viewer", + "Time-lapse": "Time-lapse", + "Montage": "Montage", + "Accounts": "Accounts", + "Settings": "Settings", + "Recording FPS": "Recording FPS", + "Input Selector": "Input Selector", + "Input Settings": "Input Settings", + "Connection": "Connection", + "API": "API", + "ONVIF": "ONVIF", + "FFprobe": "Probe", + "Filters": "Filters", + "Full URL Path": "Full URL Path", + "Logs": "Logs", + "Full Stream URL": "Full Stream URL", + "Manual": "Manual", + "List Toggle": "List Toggle", + "Hide List": "Hide List", + "Motion GUI": "Motion GUI", + "Motion": "Motion", + "Global Detector Settings": "Global Detector Settings", + "Motion Detection": "Motion Detection", + "Object Detection": "Object Detection", + "JPEG Mode": "JPEG Mode", + "Order Streams": "Order Streams", + "Hide Notes": "Hide Notes", + "Example": "Example", + "Logout": "Logout", + "Closed": "Closed", + "Ended": "Ended", + "Options": "Options", + "Started": "Started", + "Monitor": "Monitor", + "Filename": "Filename", + "Size (mb)": "Size (mb)", + "Watch": "Watch", + "Download": "Download", + "Delete": "Delete", + "Fix": "Fix", + "Use HTML5 Play Method": "Use HTML5 Play Method", + "Connection timed out": "Connection timed out", + "skipPingText1": "Try setting \"Skip Ping\" to Yes.", + "Ping Failed": "Ping Failed", + "Zoom In": "Zoom In URL Address", + "Zoom Out": "Zoom Out URL Address", + "Enable Nightvision": "Enable Nightvision", + "Disable Nightvision": "Disable Nightvision", + "Current": "Current", + "Monitors": "Monitors", + "Video": "Video", + "Themes": "Themes", + "Videos": "Videos", + "Events": "Events", + "Streams": "Streams", + "Snapshot": "Snapshot", + "Snapshots": "Snapshots", + "Date Range": "Date Range", + "Event Limit": "Event Limit", + "No Data": "No Data", + "Live View": "Live View", + "New Monitor": "New Monitor", + "Please Check Your Settings": "Please Check Your Settings", + "migrateText1": "Input Type could not be parsed. Please set it manually.", + "Add": "Add", + "Save": "Save", + "Close": "Close", + "Secure": "Secure", + "Check": "Check", + "Stop": "Stop", + "Confirm": "Confirm", + "Enable": "Enable", + "Enabled": "Enabled", + "API Key": "API Key", + "API Keys": "API Keys", + "Group Key": "Group Key", + "Allowed IPs": "Allowed IPs", + "Separate with commas, no spaces": "Separate with commas, no spaces", + "Can Get Monitors": "Can Get Monitors", + "Can Get Logs": "Can Get Logs", + "Can Authenticate Websocket": "Can Authenticate Websocket", + "Can Control Monitors": "Can Control Monitors", + "Can View Snapshots": "Can View Snapshots", + "Can View Streams": "Can View Streams", + "Can View Videos": "Can View Videos", + "Can View Monitor": "Can View Monitor", + "Can Edit Monitor": "Can Edit Monitor", + "Can Delete Videos": "Can Delete Videos", + "Delete Video": "Delete Video", + "Can View Videos and Events": "Can View Videos and Events", + "Can Delete Videos and Events": "Can Delete Videos and Events", + "Saved Filters": "Saved Filters", + "Filter Name": "Filter Name", + "Find Where": "Find Where", + "Sort By": "Sort By", + "Start Time": "Start Time", + "End Time": "End Time", + "Monitor ID": "Monitor ID", + "File Type": "File Type", + "Filesize": "Filesize", + "Video Status": "Video Status", + "Preferences": "Preferences", + "Equal to": "Equal to", + "Not Equal to": "Not Equal to", + "Greater Than or Equal to": "Greater Than or Equal to", + "Greater Than": "Greater Than", + "Less Than": "Less Than", + "Less Than or Equal to": "Less Than or Equal to", + "Like": "Like", + "Matches": "Matches", + "Not Matches": "Not Matches", + "In": "In", + "Not In": "Not In", + "ASC": "ASC", + "DESC": "DESC", + "Action for Selected": "Action for Selected", + "Search": "Search", + "No": "No", + "Yes": "Yes", + "Start": "Start", + "End": "End", + "Archive": "Archive", + "Email Details": "Email Details", + "Delete Matches": "Delete Matches", + "Delete selected": "Delete selected", + "Execute Command": "Execute Command", + "for Global Access": "for Global Access", + "Help": "Help", + "Don't show this anymore": "Don't show this anymore", + "Chat on Discord": "Chat on Discord", + "Documentation": "Documentation", + "All Monitors": "All Monitors", + "Motion Meter": "Motion Meter", + "FFmpegTip": "FFprobe is a simple multimedia streams analyzer. You can use it to output all kinds of information about an input including duration, frame rate, frame size, etc.", + "Complete Stream URL": "Complete Stream URL", + "ONVIF Scanner": "ONVIF Scanner", + "Scan Settings": "Scan Settings", + "ONVIFnote": "Discover ONVIF devices on networks outside your own or leave it blank to scan your current network.
Username and Password can be left blank.", + "Range or Single": "Range or Single", + "IP Address": "IP Address", + "Port": "Port", + "Camera Username": "Camera Username", + "Camera Password": "Camera Password", + "Found Devices": "Found Devices", + "Switch on for Still Image": "Switch on for Still Image", + "Live Stream Toggle": "Live Stream Toggle", + "RegionNote": "Points are only saved when you press Save on the Monitor Settings window.", + "Points": "Points When adding points click on the edge of the polygon.", + "Indifference": "Indifference", + "Region Name": "Region Name", + "Regions": "Regions", + "Again": "Again", + "Account Info": "Account Info", + "blankPassword": "Leave blank to keep same password", + "2-Factor Authentication": "2-Factor Authentication", + "Max Storage Amount": "Max Storage Amount in Megabytes", + "Number of Days to keep": "Number of Days to keep", + "Monitor Groups": "Monitor Groups", + "Group Name": "Group Name", + "WebDAV": "WebDAV", + "URL": "URL", + "Autosave": "Autosave", + "Save Directory": "Save Directory", + "CSS": "CSS Style your dashboard.", + "Force Monitors Per Row": "Force Monitors Per Row", + "Monitors per row": "Monitors per row for Montage", + "Browser Console Log": "Browser Console Log", + "All Monitors and Privileges": "All Monitors and Privileges", + "Permissions": "Permissions", + "Time-lapse Tool": "Time-lapse Tool", + "total": "total", + "MB": "MB", + "Calendar": "Calendar", + "Leave blank for random.": "Leave blank for random.", + "Currently viewing": "Currently viewing", + "Status Indicator": "Status Indicator", + "Show Logs": "Show Logs", + "Videos List": "Videos List", + "Monitor Settings": "Monitor Settings", + "Enlarge": "Enlarge", + "Fullscreen": "Fullscreen", + "Value": "Value", + "Idle": "Idle", + "Disabled": "Disabled", + "Record": "Record", + "Watch Only": "Watch Only", + "Toggle Sidebar": "Toggle Sidebar", + "Add Monitor": "Add Monitor", + "Start Recording": "Start Recording", + "Set to Watch Only": "Set to Watch Only", + "Save as": "Save as", + "Add New": "Add New", + "Delete Selected Videos": "Delete Selected Videos", + "DeleteSelectedVideosMsg": "Do you want to delete these videos? You cannot recover them.", + "clientStreamFailedattemptingReconnect": "Client side ctream check failed, attempting reconnect.", + "Delete Filter": "Delete Filter", + "confirmDeleteFilter": "Do you want to delete this filter? You cannot recover it.", + "Fix Video": "Fix Video", + "FixVideoMsg": "Do you want to fix this video? You cannot undo this action.", + "DeleteVideoMsg": "Do you want to delete this video? You cannot recover it.", + "dropBoxSuccess": "Success! Files saved to your Dropbox.", + "API Key Deleted": "API Key Deleted", + "APIKeyDeletedText": "Key has been deleted. It will no longer work.", + "API Key Added": "API Key Added", + "APIKeyAddedText": "You may use this key now.", + "Update": "Update", + "Update to Master": "Update to Master", + "Update to Development": "Update to Development", + "Filters Updated": "Filters Updated", + "FiltersUpdatedText": "Your changes have been saved and applied.", + "Settings Changed": "Settings Changed", + "SettingsChangedText": "Your settings have been saved and applied. Some settings may require a refresh of this page.", + "Are you sure?": "Are you sure?", + "Import Monitor Configuration": "Import Monitor Configuration", + "ImportMultiMonitorConfigurationText": "Doing this will overrwrite any monitors with IDs existing in the import file.", + "ImportMonitorConfigurationText": "Doing this will overrwrite any changes currently not saved. Imported changes will only be applied when you press Save.", + "Paste JSON here.": "Paste JSON here.", + "Delete Monitor": "Delete Monitor", + "DeleteMonitorText": "Do you want to delete this monitor? You cannot recover it. The files for this ID will remain in the filesystem. If you choose to recreate a monitor with the same ID the videos and events will become visible in the dashboard.", + "DeleteMonitorsText": "Do you want to delete these monitors? You cannot recover them. The files for these IDs will remain in the filesystem. If you choose to recreate a monitor with one of the IDs the videos and events will become visible in the dashboard.", + "Invalid JSON": "Invalid JSON", + "InvalidJSONText": "Please ensure this is a valid JSON string for Shinobi monitor configuration.", + "Passwords don't match": "Passwords don't match", + "No Events found for this video": "No Events found for this video", + "Video and Time Span (Minutes)": "Video and Time Span (Minutes)", + "Video Length (minutes) and Motion Count per video": "Video Length (minutes) and Motion Count per video", + "Counts of Motion": "Counts of Motion", + "Unable to Launch": "Unable to Launch", + "UnabletoLaunchText": "Please save new monitor first. Then attempt to launch the region editor.", + "NoVideosFoundForDateRange": "No Videos found in this date range. Try setting the start date further back.", + "monitorEditFailedMaxReached": "Your account has reached the maximum number of cameras that can be created. Speak to an administrator if you would like this changed.", + "in": "in", + "ago": "ago", + "a few seconds": "a few seconds", + "a minute": "a minute", + "minutes": "minutes", + "an hour": "an hour", + "hours": "hours", + "a day": "a day", + "days": "days", + "a month": "a month", + "months": "months", + "a year": "a year", + "years": "years", + "Identity": "Identity", + "Input": "Input", + "Input Feed": "Input Feed", + "Stream": "Stream", + "Stream Timestamp": "Stream Timestamp", + "Stream Watermark": "Stream Watermark", + "JPEG API": "JPEG API Snapshot (cgi-bin)", + "Raw H.264 Stream": "Raw H.264 Stream", + "Recording": "Recording", + "Recording Timestamp": "Recording Timestamp", + "Recording Watermark": "Recording Watermark", + "Region Editor": "Region Editor", + "Custom": "Custom", + "Detector": "Detector", + "Connected": "Connected", + "Not Saved": "Not Saved", + "Not Connected": "Not Connected", + "Lisence Plate Detector": "Lisence Plate Detector", + "OpenCV Cascades": "OpenCV Cascades", + "Refresh List of Cascades": "Refresh List of Cascades", + "\"No Motion\" Detector": "\"No Motion\" Detector", + "Control": "Control", + "Grouping": "Grouping Add groups in Settings", + "Detector Grouping": "Detector Grouping Add groups in Settings", + "Logging": "Logging", + "IdentityText1": "This is how the system will identify the data for this stream. You cannot change the Monitor ID once you have pressed save. If you want you can make the Monitor ID more human readable before you continue.", + "IdentityText2": "You can duplicate a monitor by modifying the Monitor ID then pressing save. You cannot use the ID of a monitor that already exists or it will save over that monitor's database information.", + "noSpecialCharacters": "No spaces or special characters.", + "NotesPlacholder": "Comments you want to leave for this cameras settings.", + "InputText1": "This section tells Shinobi how to consume a stream. For optimal performance try tuning your camera's internal settings. Find the following options and set them as shown. To find your camera you can use the built in ONVIF Scanner of Shinobi. Some ONVIF cameras require the use of a management tool to modify their internal settings. If you can't find your cameras you can try ONVIF Device Manager for Windows.", + "InputText2": "
  • Framerate (FPS) : High : 10 - 15 FPS, Low : 2-5 FPS
  • I-frame interval : 80
  • Bit Rate Type : CBR (Constant Bit Rate)
  • Bit Rate : between 256kbps - 500kbps
", + "InputText3": "If you need help figuring out what input type your camera is you can take a look in the Camera URLs List on the Shinobi website.", + "StreamText": "

This section will designate the primary method of streaming out and its settings. This stream will be displayed in the dashboard. If you choose to use HLS, JPEG, or MJPEG then you can consume the stream through other programs.

Using JPEG stream essentially turns off the primary stream and uses the snapshot bin to get frames.

", + "DetectorText": "

When the Width and Height boxes are shown you should set them to 640x480 or below. This will optimize the read speed of frames.

", + "RecordingText": "It is recommended that you set Record File Type to WebMMP4 and Video Codec to libvpxcopy or libx264 because your Input Type is set to .", + "Mode": "Mode", + "Name": "Name", + "Skip Ping": "Skip Ping", + "Retry Connection": "Retry Connection Number of times allowed to fail", + "Notes": "Notes", + "Input Type": "Input Type", + "Connection Type": "Connection Type", + "RTSP Transport": "RTSP Transport", + "Host": "Host", + "Force Port": "Force Port", + "Path": "Path", + "Monitor Capture Rate": "Monitor Capture Rate (FPS)", + "Analyzation Duration": "Analyzation Duration", + "Probe Size": "Probe Size", + "Stream Type": "Stream Type", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "HLS Video Encoder": "Video Encoder", + "HLS Audio Encoder": "Audio Encoder", + "HLS Segment Length": "Segment Length in Seconds", + "HLS Preset": "Preset Template", + "HLS List Size": "List Size", + "Traditional Recording": "Traditional Recording", + "Buffer Preview": "Buffer Preview", + "HLS Start Number": "HLS Start Number", + "HLS Live Start Index": "HLS Live Start Index", + "Check Signal Interval": "Check Signal Interval in Minutes", + "Log Signal Event": "Log Signal Event Client side only", + "Quality": "Quality 1 is High, 23 is Low", + "Rate": "Rate (FPS)", + "Width": "Width", + "Height": "Height", + "Rotate": "Rotate", + "Primary Engine": "Primary Engine", + "Video Filter": "Video Filter", + "Font Path": "Font Path", + "Font Size": "Font Size", + "Text Color": "Text Color", + "Text Box Color": "Text Box Color", + "Position X": "Position X", + "Position Y": "Position Y", + "Image Location": "Image Location Absolute Path or leave blank to use global", + "Image Position": "Image Position", + "Frame Rate": "Frame Rate (FPS)", + "Image Width": "Image Width", + "Image Height": "Image Height", + "Record File Type": "Record File Type", + "Video Codec": "Video Codec", + "Preset": "Preset", + "Audio Codec": "Audio Codec", + "Video Record Rate": "Video Record Rate (FPS)", + "Record Width": "Record Width", + "Record Height": "Record Height", + "Double Quote Directory": "Double Quote Directory Some directories have spaces. Using this may crash some cameras.", + "Recording Segment Interval": "Recording Segment Interval in minutes", + "Record Video Filter": "Record Video Filter", + "Input Flags": "Input Flags", + "Snapshot Flags": "Snapshot Flags", + "Detector Flags": "Detector Flags", + "Stream Flags": "Stream Flags", + "Stream to YouTube": "Stream to YouTube", + "Stream to YouTube Flags": "Stream to YouTube Flags", + "Recording Flags": "Recording Flags", + "Output Method": "Output Method", + "Webhook": "Webhook", + "Webhook URL": "Webhook URL", + "Command on Trigger": "Command on Trigger", + "Command": "Command", + "Allow Next Command": "Allow Next Command in Minutes", + "Allow Next Trigger": "Allow Next Trigger in Milliseconds", + "Save Events to SQL": "Save Events to SQL", + "Email on Trigger": "Email on Trigger Emails go to the main account holder's login address.", + "Allow Next Email": "Allow Next Email in Minutes", + "How to Record": "How to Record", + "Trigger Record": "Trigger Record", + "Recording Timeout": "Recording Timeout in Minutes", + "Timeout Reset on Next Motion": "Timeout Reset on Next Motion", + "Timeout Reset on Next Event": "Timeout Reset on Next Event", + "Delete Motionless Video": "Delete Motionless Video", + "Send Frames": "Send Frames Push frames to be analyzed", + "Detector Rate": "Detector Rate (FPS)", + "Feed-in Image Width": "Feed-in Image Width", + "Feed-in Image Height": "Feed-in Image Height", + "Check for Motion First": "Check for Motion First", + "Detect Objects": "Detect Objects See below", + "Full Frame Detection": "Full Frame Detection", + "Country of Plates": "Country of Plates", + "Email on No Motion": "Email on \"No Motion\"", + "Timeout": "Timeout", + "Controllable": "Controllable", + "Custom Base URL": "Custom Base URL Leave blank to use Host URL", + "Stop URL": "Stop URL", + "Stop Command": "Stop Command", + "Digest Authentication": "Digest Authentication", + "URL Stop Timeout": "URL Stop Timeout Run stop URL after X milliseconds", + "Center": "Center URL Address", + "Left": "Left URL Address", + "Left Stop": "Left Stop URL Address", + "Right": "Right URL Address", + "Right Stop": "Right Stop URL Address", + "Up": "Up URL Address", + "Up Stop": "Up Stop URL Address", + "Down": "Down URL Address", + "Down Stop": "Down Stop URL Address", + "Enable Night Vision": "Enable Night Vision URL Address", + "Disable Night Vision": "Disable Night Vision URL Address", + "Zoom Out Stop": "Zoom Out Stop URL Address", + "Zoom In Stop": "Zoom In Stop URL Address", + "Log Level": "Log Level", + "Save Log in SQL": "Save Log in SQL This can fill up quickly.", + "JPEG": "JPEG", + "MJPEG": "MJPEG", + "H.264 / H.265 / H.265+": "H.264 / H.265 / H.265+", + "HLS (.m3u8)": "HLS (.m3u8)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)", + "Shinobi Streamer": "Shinobi Streamer", + "Dashcam (Streamer v2)": "Dashcam (Streamer v2)", + "Local": "Local", + "Raw": "Raw", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "RTSP": "RTSP", + "RTMP": "RTMP", + "RTMPS": "RTMPS", + "UDP": "UDP", + "Auto": "Auto", + "TCP": "TCP", + "Base64 over Websocket": "Base64 over Websocket", + "Websocket": "Websocket", + "JPEG (Auto Enables JPEG API)": "JPEG (Auto Enables JPEG API)", + "HLS (includes Audio)": "HLS (includes Audio)", + "MPEG-DASH (includes Audio)": "MPEG-DASH (includes Audio)", + "libx264": "libx264", + "libx265": "libx265", + "copy": "copy", + "No Audio": "No Audio", + "aac": "aac", + "ac3": "ac3", + "libmp3lame": "libmp3lame", + "No Rotation": "No Rotation", + "180 Degrees": "180 Degrees", + "90 Counter Clockwise and Vertical Flip (default)": "90 Counter Clockwise and Vertical Flip (default)", + "90 Clockwise": "90 Clockwise", + "90 Clockwise and Vertical Flip": "90 Clockwise and Vertical Flip", + "Top Right": "Top Right", + "Top Left": "Top Left", + "Bottom Right": "Bottom Right", + "Bottom Left": "Bottom Left", + "WebM (libvpx)": "WebM (libvpx)", + "Poseidon": "Poseidon", + "MP4 (copy, libx264, libx265)": "MP4 (copy, libx264, libx265)", + "Default": "Default", + "libvpx (Default)": "libvpx (Default)", + "libvpx-vp9": "libvpx-vp9", + "libx264 (Default)": "libx264 (Default)", + "libvorbis (Default)": "libvorbis (Default)", + "libopus": "libopus", + "aac (Default)": "aac (Default)", + "Traditional (Watch-Only, Includes Buffer)": "Traditional (Watch-Only, Includes Buffer)", + "Hotswap Modes (Watch-Only)": "Hotswap Modes (Watch-Only)", + "Delete Motionless Videos (Record)": "Delete Motionless Videos (Record)", + "US": "US", + "EU": "EU", + "Silent": "Silent", + "Fatal": "Fatal", + "on Error": "on Error", + "All Warnings": "All Warnings", + "Warning": "Warning", + "Debug": "Debug", + "Export": "Export", + "Import": "Import", + "Simple": "Simple", + "Advanced": "Advanced", + "Error Connecting": "Error Connecting", + "DB Lost.. Retrying..": "Database Lost.. Retrying..", + "Retrying...": "Retrying...", + "Filter Matches": "Filter Matches", + "FilterMatchesText1": "This filter has met conditions.", + "FilterMatchesText2": "videos found.", + "Executed": "Executed", + "Deleted": "Deleted", + "Query": "Query", + "Request": "Request", + "System": "System", + "Restart Core": "Restart Core", + "Restart CRON": "Restart CRON", + "Flush PM2 Logs": "Flush PM2 Logs", + "Filter ID": "Filter ID", + "Webdav Error": "Webdav Error", + "WebdavErrorText": "Cannot save. Did you make the camera folders inside your chosen save directory?", + "File Not Exist": "File Not Exist", + "No Videos Found": "No Videos Found", + "FileNotExistText": "Cannot save non existant file. Something went wrong.", + "CameraNotRecordingText": "Settings may be incompatible. Check encoders. Restarting...", + "Camera is not recording": "Camera is not recording", + "Camera is not streaming": "Camera is not streaming", + "Restarting Process": "Restarting Process", + "Restart": "Restart", + "Monitor Stopped": "Monitor Stopped", + "MonitorStoppedText": "Monitor session has been ordered to stop.", + "Monitor Idling": "Monitor Idling", + "MonitorIdlingText": "Monitor session has been ordered to idle.", + "NoMotionEmailText1": "No Motion for", + "NoMotionEmailText2": "There hasn't been any motion detected on camera for", + "Monitor Name": "Monitor Name", + "Process Unexpected Exit": "Process Unexpected Exit", + "Process Crashed for Monitor": "Process Crashed for Monitor", + "FFmpegCantStart": "FFmpeg Couldn't Start", + "FFmpegCantStartText": "The recording engine for this camera could not start. There may be something wrong with your camera configuration. If there are any logs other than this one please post them in the Issues on Github.", + "JPEG Error": "JPEG Error", + "JPEGErrorText": "There was an issue getting data from your camera.", + "Fatal Maximum Reached": "Fatal Maximum Reached, Stopping Camera.", + "FatalMaximumReachedText": "JPEG Error was fatal.", + "Incorrect Settings Chosen": "Incorrect Settings Chosen", + "Can't Connect": "Can't Connect", + "Video Finished": "Video Finished", + "No Monitors Selected": "No Monitors Selected", + "monSavedButNotCopied": "Your monitor was saved but not copied to any other monitor.", + "No Monitor Found, Ignoring Request": "No Monitor Found, Ignoring Request", + "Event": "Event", + "Detector Buffer": "Detector Buffer", + "EventText1": "Triggered a motion event at", + "EventText2": "Could not email image, file was not accessible", + "MailError": "MAIL ERROR : Could not send email, Check conf.json. Skipping any features relying on mailing.", + "updateKeyText1": "\"updateKey\" is missing from \"conf.json\", cannot do updates this way until you add it.", + "updateKeyText2": "\"updateKey\" is incorrect.", + "Control Error": "Control Error", + "ControlErrorText1": "Control is not enabled", + "ControlErrorText2": "Check your connection details. You may need to point the Base URL at port 8000 or 80. Check your authentication info.", + "NotAuthorizedText1": "Not Authorized, Submit init command with \"auth\",\"ke\", and \"uid\"", + "Fields cannot be empty": "Fields cannot be empty", + "AccountEditText1": "Could not edit. Refresh page if problem continues.", + "Not an Administrator Account": "Not an Administrator Account", + "superAdminText": "\"super.json\" does not exist. Please rename \"super.sample.json\" to \"super.json\".", + "Enter this code to proceed": "Enter this code to proceed", + "FactorAuthText1": "The code will only be active for 15 minutes. If you login again the timer will be reset to 15 minutes with the same code.", + "monitorEditText1": "Invalid Data, Check to see this is a valid import string.", + "monitorEditText2": "Invalid Details String. Check to see it is a JSON string and not a regular object being passed.", + "Monitor Updated by user": "Monitor Updated by user.", + "Monitor Added by user": "Monitor Added by user.", + "monitorGetText1": "incomplete request, remove last slash in URL or put acceptable value.", + "Monitor mode changed": "Monitor mode changed", + "Reset Timer": "Reset Timer", + "Monitor mode is already": "Monitor mode is already", + "Monitor or Key does not exist.": "Monitor or Key does not exist.", + "No Group with this key exists": "No Group with this key exists", + "Trigger Successful": "Trigger Successful", + "No such file": "No such file", + "modifyVideoText1": "Method doesn't exist. Check to make sure that the last value of the URL is not blank.", + "CPU indicator will not work. Continuing...": "CPU indicator will not work. Continuing...", + "startUpText0": "size check for videos", + "startUpText1": "end of size check for videos", + "startUpText2": "all users checked, wait to close open files and remove files over user limit", + "startUpText3": "waiting to give unfinished video check some time. 3 seconds.", + "startUpText4": "starting all monitors set to watch and record", + "startUpText5": "Shinobi is ready.", + "Migrator": "Migrator", + "Host Type": "Host Type", + "Edit": "Edit", + "Dashboard Language": "Dashboard Language", + "File Not Found": "File Not Found", + "File Not Found in Filesystem": "File Not Found in Filesystem", + "File Not Found in Database": "File Not Found in Database", + "No Monitor Exists with this ID.": "No Monitor Exists with this ID.", + "Cannot watch a monitor that isn't running.": "Cannot watch a monitor that isn't running.", + "Not Permitted": "Not Permitted", + "notPermitted1": "This action is not permitted by the administrator of your account.'", + "Not Authorized": "Not Authorized", + "Generate Subtitles": "Generate Subtitles", + "Video Limit":"Video Limit", + "Preview":"Preview", + "Websocket Connected":"Websocket Connected", + "Websocket Disconnected":"Websocket Disconnected", + "New Authentication Token":"New Authentication Token", + "All Logs":"All Logs", + "For Group":"For Group", + "Basic Authentication":"Basic Authentication", + "Superuser Logs":"Superuser Logs", + "Authentication Failed":"Authentication Failed", + "Max Number of Cameras":"Max Number of Cameras", + "Can edit Max Storage":"Can edit Max Storage", + "Can edit Max Days":"Can edit Max Days", + "in Days":"in Days", + "Can edit how long to keep Logs":"Can edit how long to keep Logs", + "Can use Admin Panel":"Can use Admin Panel", + "Can use WebDAV":"Can use WebDAV", + "Can use LDAP":"Can use LDAP", + "Can edit how long to keep Events":"Can edit how long to keep Events", + "Leave blank for unlimited":"Leave blank for unlimited", + "Limited":"Limited", + "All Privileges":"All Privileges", + "LDAP":"LDAP", + "LDAP Success":"LDAP Success", + "LDAP User Authenticated":"LDAP User Authenticated", + "LDAP User is New":"LDAP User is New", + "Creating New Account":"Creating New Account", + "bindDN":"bindDN", + "Bind Credentials":"Bind Credentials (Password)", + "Search Base":"Search Base", + "Configuration":"Configuration", + "Blank for No Change":"Blank for No Change", + "Pop":"Pop", + "Recording FPS Change on Start":"Recording FPS Change on Start", + "Save Frames to Events":"Save Frames to Events", + "Search Filter":"Search Filter", + "h264_cuvid": "H.264 CUVID", + "hevc_cuvid": "H.265 CUVID", + "mjpeg_cuvid": "MJPEG CUVID", + "mpeg4_cuvid": "MPEG4 CUVID", + "h264_qsv": "H.264 (Quick Sync Video)", + "hevc_qsv": "H.265 (Quick Sync Video)", + "vp8_qsv": "VP8 (Quick Sync Video)", + "mpeg2_qsv": "MPEG2 (Quick Sync Video)", + "h264_vaapi": "H.264 VA-API (Intel HW Accel)", + "h264_nvenc": "H.264 NVENC (NVIDIA HW Accel)", + "hevc_nvenc": "H.265 NVENC (NVIDIA HW Accel)", + "hevc_vaapi": "H.265 VA-API (Intel HW Accel)", + "vp8_cuvid": "VP8 NVENC (NVIDIA HW Accel)", + "vp9_cuvid": "VP9 NVENC (NVIDIA HW Accel)", + "hwaccel": "Acceleration Engine", + "hwaccel_vcodec": "Video Decoder", + "hwaccel_device": "HWAccel Device", + "Get Logs to Client": "Get Logs to Client", + "Hardware Accelerated": "Hardware Accelerated", + "Accelerator": "Accelerator", + "qsv": "qsv", + "dxva2": "dxva2 (DirectX Video, Windows)", + "vdpau": "vdpau", + "vaapi": "vaapi (VA-API)", + "vda": "vda (Apple VDA Hardware Acceleration)", + "videotoolbox": "videotoolbox", + "cuvid": "cuvid (NVIDIA NVENC)", + "Main": "Main", + "Storage Location": "Storage Location", + "Recommended": "Recommended", + "Please Wait for Completion": "Please Wait for Completion, Depending on the number of files selected this may take some time. Refresh to check again.", + "flv": "flv", + "FLV": "FLV", + "FLV Stream Type": "FLV Stream Type", + "Link Shinobi": "Link Shinobi", + "Show Stream HUD":"Show Stream HUD", + "Call Method":"Call Method", + "Gender":"Gender", + "Emotion":"Emotion", + "Age":"Age", + "Object":"Object", + "Uniform":"Uniform", + "Pose":"Pose", + "Male":"Male", + "Female":"Female", + "Channel":"Channel", + "Stream Key":"Stream Key", + "Server URL":"Server URL", + "Video Bit Rate":"Video Bit Rate", + "Audio Bit Rate":"Audio Bit Rate", + "RTMP Stream Flags":"RTMP Stream Flags", + "RTMP Stream":"RTMP Stream", + "Stream Channel":"Stream Channel", + "Confidence":"Confidence", + "Map":"Map", + "Add Map":"Add Map", + "Add Input Feed":"Add Input Feed", + "Add Channel":"Add Channel", + "Automatic":"Automatic", + "Max Latency":"Max Latency", + "Loop Stream":"Loop Stream", + "Object Tag":"Object Tag", + "Noise Filter":"Noise Filter", + "Noise Filter Range":"Noise Filter Range", + "TV Channel":"TV Channel", + "Channel ID":"Channel ID", + "TV Channel ID":"TV Channel ID", + "TV Channel Group":"TV Channel Group", + "Emotion Average":"Emotion Average", + "Show Regions of Interest":"Show Regions of Interest", + "Confidence of Detection":"Confidence of Detection", + "Edit Selected":"Edit Selected", + "Copy Settings":"Copy Settings", + "Copy to Settings":"Copy to Settings", + "Copy Group Settings":"Copy Group Settings", + "Copy Connection Settings":"Copy Connection Settings", + "Copy Custom Settings":"Copy Custom Settings", + "Copy Logging Settings":"Copy Logging Settings", + "Copy JPEG API Settings":"Copy JPEG API Settings", + "Copy Input Settings":"Copy Input Settings", + "Copy Stream Settings":"Copy Stream Settings", + "Copy Stream Channel Settings":"Copy Stream Channel Settings", + "Copy Recording Settings":"Copy Recording Settings", + "Copy Detector Settings":"Copy Detector Settings", + "Monitors to Copy to":"Monitors to Copy to", + "Notification Sound":"Notification Sound", + "Alert Sound":"Alert Sound", + "Alert Sound Delay":"Alert Sound Delay", + "powerVideoEventLimit":"You have set a high event limit. Are you sure you want to make this request?", + "There are no monitors that you can view with this account.":"There are no monitors that you can view with this account.", + "Use Built-In":"Use Built-In" +} diff --git a/languages/fr.json b/languages/fr.json new file mode 100644 index 0000000..41b0358 --- /dev/null +++ b/languages/fr.json @@ -0,0 +1,666 @@ +{ + "\"No Motion\" Detector": "\"Aucun Mouvement\" Détecteur De", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "180 Degrees": "180 Degrés", + "2-Factor Authentication": "Une Authentification À 2 Facteurs", + "90 Clockwise": "90 dans le sens des Aiguilles", + "90 Clockwise and Vertical Flip": "90 vers la gauche et Vertical Flip", + "90 Counter Clockwise and Vertical Flip (default)": "90 dans le sens antihoraire et la rotation Verticale (par défaut)", + "API": "API", + "API Key": "Clé API", + "API Key Added": "Clé API Ajouté", + "API Key Deleted": "API Clé Supprimée", + "API Keys": "Clés API", + "APIKeyAddedText": "Vous pouvez utiliser cette clé maintenant.", + "APIKeyDeletedText": "Clé a été supprimé. Elle ne fonctionnera plus.", + "ASC": "ASC", + "Accelerator": "Accélérateur", + "Account Info": "Les Informations De Compte", + "AccountEditText1": "Ne pouvait pas modifier. Actualiser la page si le problème persiste.", + "Accounts": "Comptes", + "Action for Selected": "Action Sélectionnés", + "Add": "Ajouter", + "Add Channel": "Ajouter Un Canal", + "Add Input Feed": "Ajoutez D'Entrée D'Alimentation", + "Add Map": "Ajouter La Carte", + "Add Monitor": "Ajouter Moniteur", + "Add New": "Ajouter De Nouveaux", + "Admin": "Admin", + "Advanced": "Avancé", + "Again": "Encore", + "Age": "L'âge", + "All Logs": "Tous Les Journaux", + "All Monitors": "Tous Les Moniteurs", + "All Monitors and Privileges": "Tous les Moniteurs et Privilèges", + "All Privileges": "Tous Les Privilèges", + "All Warnings": "Tous Les Avertissements", + "Allow Next Command": "Permettre Prochaine Commande en quelques Minutes", + "Allow Next Email": "Permettre Prochain Email en quelques Minutes", + "Allow Next Trigger": "Permettre à Côté de Déclenchement en Millisecondes", + "Allowed IPs": "Permis IPs", + "Analyzation Duration": "Analyzation Durée", + "Archive": "Archive", + "Are you sure?": "Êtes-vous sûr?", + "Audio Bit Rate": "Le Débit Binaire Audio", + "Audio Codec": "Codec Audio", + "Authenticate": "Authentifier", + "Authentication Failed": "Échec De L'Authentification", + "Auto": "Auto", + "Automatic": "Automatique", + "Autosave": "Autosave", + "Base64 over Websocket": "Base64 sur Websocket", + "Basic Authentication": "L'Authentification De Base", + "Bind Credentials": "Lier Les Informations D'Identification (Mot De Passe)", + "Blank for No Change": "Vide pour Pas Changer", + "Bottom Left": "En Bas À Gauche", + "Bottom Right": "En Bas À Droite", + "Browser Console Log": "Le Navigateur De La Console De Log", + "Buffer Preview": "Tampon Aperçu", + "CPU": "CPU", + "CPU indicator will not work. Continuing...": "CPU indicateur ne fonctionnera pas. Continue...", + "CSS": "CSS Style de votre tableau de bord.", + "Calendar": "Calendrier", + "Call Method": "Appel De La Méthode", + "Camera Password": "Mot De Passe De La Caméra", + "Camera Username": "Nom D'Utilisateur De La Caméra", + "Camera is not recording": "Appareil photo n'est pas de l'enregistrement", + "Camera is not streaming": "La caméra n'est pas en streaming", + "CameraNotRecordingText": "Les paramètres peuvent être incompatibles. Vérifier les encodeurs. Le redémarrage...", + "Can Authenticate Websocket": "Peut Authentifier Websocket", + "Can Control Monitors": "Peut Moniteurs De Contrôle", + "Can Delete Videos": "Pouvez Supprimer Des Vidéos", + "Can Delete Videos and Events": "Pouvez Supprimer des Vidéos et des Événements", + "Can Edit Monitor": "Pouvez Modifier Moniteur", + "Can Get Logs": "Pouvez Obtenir Les Journaux", + "Can Get Monitors": "Pouvez Obtenir Des Moniteurs", + "Can View Monitor": "Peut Moniteur De Vue", + "Can View Snapshots": "Peut Afficher Des Instantanés", + "Can View Streams": "Peut Afficher Des Flux", + "Can View Videos": "Peut Visionner Des Vidéos", + "Can View Videos and Events": "Pouvez Visualiser des Vidéos et des Événements", + "Can edit Max Days": "Pouvez éditer Max Jours", + "Can edit Max Storage": "Pouvez éditer Max de Stockage", + "Can edit how long to keep Events": "Pouvez modifier la durée de conservation des Événements", + "Can edit how long to keep Logs": "Pouvez modifier la durée de conservation des Journaux d'", + "Can use Admin Panel": "Pouvez utiliser le Panneau d'administration", + "Can use LDAP": "Peut utiliser le protocole LDAP", + "Can use WebDAV": "Pouvez utiliser WebDAV", + "Can't Connect": "Ne peut pas se Connecter", + "Cannot watch a monitor that isn't running.": "Impossible de regarder un moniteur qui n'est pas en cours d'exécution.", + "Center": "Centre d' Adresse URL", + "Channel": "Canal", + "Channel ID": "ID de canal", + "Chat on Discord": "Chat sur la Discorde", + "Check": "Vérifier", + "Check Signal Interval": "Vérifier le Signal de l'Intervalle en Minutes", + "Check for Motion First": "Vérifier le Mouvement de la Première", + "Close": "Fermer", + "Closed": "Fermé", + "Command": "Commande", + "Command on Trigger": "Commande sur la Gâchette", + "Complete Stream URL": "Compléter l'URL du Flux", + "Confidence": "La confiance", + "Confidence of Detection": "La confiance de Détection", + "Configuration": "Configuration", + "Confirm": "Confirmer", + "Connected": "Connecté", + "Connection": "Connexion", + "Connection Type": "Type De Connexion", + "Control": "Contrôle", + "Control Error": "Erreur De Contrôle De La", + "ControlErrorText1": "Le contrôle n'est pas activé", + "Controllable": "Contrôlable", + "Copy Connection Settings": "Copie Des Paramètres De Connexion", + "Copy Custom Settings": "Copie Des Paramètres Personnalisés", + "Copy Detector Settings": "Copie Réglages Du Détecteur", + "Copy Group Settings": "Copier Les Paramètres De Groupe", + "Copy Input Settings": "Copier Les Paramètres D'Entrée", + "Copy Logging Settings": "Copie Des Paramètres De Journalisation", + "Copy Recording Settings": "Copier Les Paramètres D'Enregistrement", + "Copy Settings": "Paramètres De Copie", + "Copy Stream Channel Settings": "Copie De Flux De Paramètres De Canal", + "Copy Stream Settings": "Copier Les Paramètres De Flux", + "Copy to Settings": "Copie des Paramètres de", + "Country of Plates": "Pays de Plaques", + "Counts of Motion": "Comtes de Mouvement", + "Creating New Account": "La Création D'Un Nouveau Compte", + "Current": "Actuel", + "Currently viewing": "Visualisez actuellement", + "Custom": "Personnalisé", + "Custom Base URL": "Base d'URL personnalisée Laissez le champ vide pour utiliser l'Hôte de l'URL", + "DB Lost.. Retrying..": "Base De Données Perdues.. Réessayer..", + "DESC": "DESC", + "Dashboard": "Tableau de bord", + "Dashboard Language": "Langue Du Tableau De Bord", + "Dashcam": "Dashcam", + "Dashcam (Streamer v2)": "Dashcam (Streamer v2)", + "Date Range": "La Plage De Dates", + "Debug": "Debug", + "Default": "Par défaut", + "Delete": "Supprimer", + "Delete Filter": "Supprimer Le Filtre", + "Delete Matches": "Supprimer Les Matchs", + "Delete Monitor": "Supprimer Moniteur", + "Delete Motionless Video": "Supprimer Immobile Vidéo", + "Delete Motionless Videos (Record)": "Supprimer Immobile Vidéos (Enregistrement)", + "Delete Selected Videos": "Supprimer La Sélection Des Vidéos", + "Delete Video": "Supprimer La Vidéo", + "Delete selected": "Supprimer la sélection", + "DeleteMonitorText": "Voulez-vous supprimer ce moniteur? Vous ne pouvez pas le récupérer. Les fichiers de cet ID restera dans le système de fichiers. Si vous choisissez de recréer un moniteur avec le même ID, les vidéos et les événements deviennent visibles dans le tableau de bord.", + "DeleteMonitorsText": "Voulez-vous supprimer ces moniteurs? Vous ne pouvez pas les récupérer. Les fichiers de ces Identifiants de rester dans le système de fichiers. Si vous choisissez de recréer un moniteur avec un de l'IDs, les vidéos et les événements deviennent visibles dans le tableau de bord.", + "DeleteSelectedVideosMsg": "Voulez-vous supprimer ces vidéos? Vous ne pouvez pas les récupérer.", + "DeleteVideoMsg": "Voulez-vous supprimer cette vidéo? Vous ne pouvez pas le récupérer.", + "Deleted": "Supprimé", + "Detect Objects": "Détecter les Objets Voir ci-dessous", + "Detector": "Détecteur de", + "Detector Buffer": "Détecteur De Tampon", + "Detector Flags": "Détecteur De Drapeaux", + "Detector Grouping": "Détecteur de Groupement d'Ajouter des groupes de Paramètres", + "Detector Rate": "Détecteur de Taux (FPS)", + "DetectorText": "

Lorsque les zones Largeur et Hauteur sont affichés, vous devriez les mettre à 640x480 ou ci-dessous. Cela permettra d'optimiser la vitesse de lecture d'images.

", + "Disable Night Vision": "Désactiver la Vision de Nuit Adresse URL", + "Disable Nightvision": "Désactiver Nightvision", + "Disabled": "Désactivé", + "Documentation": "La Documentation", + "Don't show this anymore": "Ne pas afficher plus", + "Double Quote Directory": "Devis Double Répertoire de Certains répertoires sont séparés par des espaces. L'utilisation de ce peut se bloquer certains appareils photo.", + "Down": "Bas Adresse URL", + "Down Stop": "Vers le bas Arrêter Adresse URL", + "Download": "Télécharger", + "EU": "L'UE", + "Edit": "Modifier", + "Edit Selected": "Modifier Les", + "Email": "E-mail", + "Email Details": "E-Mail Les Détails", + "Email on No Motion": "E-mail sur \"Aucun Mouvement\"", + "Email on Trigger": "E-mail sur la Gâchette e-Mails passent à la principale du titulaire de compte de connexion l'adresse.", + "Emotion": "L'émotion", + "Emotion Average": "L'Émotion De La Moyenne", + "Enable": "Activer", + "Enable Night Vision": "Activer la Vision Nocturne Adresse URL", + "Enable Nightvision": "Activer La Vision Nocturne", + "Enabled": "Activé", + "End": "Fin", + "End Time": "Heure De Fin", + "Ended": "Terminé", + "Enlarge": "Agrandir", + "Enter this code to proceed": "Entrez ce code pour procéder", + "Equal to": "Égal à", + "Error Connecting": "Erreur Lors De La Connexion", + "Event": "L'événement", + "Event Limit": "Cas Limite", + "EventText1": "Déclenché un mouvement à", + "EventText2": "Pourrait pas l'email de l'image, le fichier n'est pas accessible", + "Events": "Les événements", + "Example": "Exemple", + "Execute Command": "Exécuter La Commande", + "Executed": "Exécuté", + "Export": "L'exportation", + "FFmpegCantStart": "FFmpeg ne Pouvait pas Commencer", + "FFmpegCantStartText": "Le moteur d'enregistrement pour cette caméra n'a pas pu démarrer. Il y a peut être quelque chose de mal avec votre configuration de la caméra. S'il y a des journaux autres que celui-ci, veuillez les poster dans les Questions sur Github.", + "FFmpegTip": "FFprobe est un simple flux multimédias de l'analyseur. Vous pouvez l'utiliser pour afficher toutes sortes d'informations sur les intrants, y compris la durée, taux d'armature, taille de l'image, etc.", + "FFprobe": "Sonde", + "FLV": "FLV", + "FLV Stream Type": "FLV Type de Flux", + "FactorAuthText1": "Le code ne sera actif pendant 15 minutes. Si vous vous connectez de nouveau la minuterie est réinitialisée à 15 minutes avec le même code.", + "Fatal": "Fatale", + "Fatal Maximum Reached": "Fatale Maximum Atteint, L'Arrêt De La Caméra.", + "FatalMaximumReachedText": "JPEG Erreur a été fatale.", + "Feed-in Image Height": "De rachat à la Hauteur de l'Image", + "Feed-in Image Width": "Alimentation sur la Largeur de l'Image", + "Female": "Femelle", + "Fields cannot be empty": "Les champs ne peut pas être vide", + "File Not Exist": "Le Fichier N'Existe Pas", + "File Not Found": "Fichier Non Trouvé", + "File Type": "Type De Fichier", + "FileNotExistText": "Impossible d'enregistrer non existant fichier. Quelque chose s'est mal passé.", + "Filename": "Filename", + "Filesize": "La taille du fichier", + "Filter ID": "Filtre ID", + "Filter Matches": "Filtre Correspond", + "Filter Name": "Nom Du Filtre", + "FilterMatchesText1": "Ce filtre a rencontré des conditions.", + "FilterMatchesText2": "les vidéos trouvées.", + "Filters": "Les filtres", + "Filters Updated": "Les Filtres Mis À Jour", + "FiltersUpdatedText": "Vos modifications ont été enregistrées et appliquées.", + "Find Where": "Trouver Où", + "Fix": "Fix", + "Fix Video": "Corriger La Vidéo", + "FixVideoMsg": "Voulez-vous corriger cette vidéo? Vous ne pouvez pas annuler cette action.", + "Flush PM2 Logs": "Rincer les PM2 Journaux", + "Font Path": "Le Chemin De Police", + "Font Size": "Taille De La Police", + "For Group": "Pour Le Groupe", + "Force Port": "La Force De Port", + "Found Devices": "Appareils Trouvés", + "Frame Rate": "Le Taux d'image par seconde(FPS)", + "Full Frame Detection": "Plein Cadre La Détection", + "Full Stream URL": "Complet de l'URL du Flux", + "Full URL Path": "Plein Chemin d'accès d'URL", + "Fullscreen": "Plein écran", + "Gender": "Genre", + "Generate Subtitles": "Générer Des Sous-Titres", + "Get Logs to Client": "Obtenir les Journaux du Client", + "Greater Than": "Plus De", + "Greater Than or Equal to": "Supérieure ou Égale à", + "Group Key": "La Clé De Groupe", + "Group Name": "Nom Du Groupe", + "Grouping": "Groupement d'Ajouter des groupes de Paramètres", + "H.264 / H.265 / H.265+": "H. 264 / H. 265 / H. 265 ", + "HLS (.m3u8)": "HLS (.m3u8)", + "HLS (includes Audio)": "HLS (Audio)", + "HLS Audio Encoder": "Encodeur Audio", + "HLS List Size": "La Taille De La Liste", + "HLS Live Start Index": "HLS Vivre Index de Début", + "HLS Preset": "Modèle Préréglé", + "HLS Segment Length": "La Longueur du Segment en quelques Secondes", + "HLS Start Number": "HLS Nombre de Départ", + "HLS Video Encoder": "Encodeur Vidéo", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "Hardware Accelerated": "L'Accélération Matérielle", + "Height": "Hauteur", + "Help": "Aider", + "Hide List": "Masquer La Liste", + "Hide Notes": "Masquer Les Notes", + "Host": "Accueil", + "Hotswap Modes (Watch-Only)": "Hotswap Modes (Watch)", + "How to Record": "Comment faire pour Enregistrer", + "IP Address": "Adresse IP", + "Identity": "Identité", + "IdentityText1": "C'est la façon dont le système permettra d'identifier les données pour ce flux. Vous ne pouvez pas modifier le Moniteur ID une fois que vous avez appuyé sur la touche enregistrer. Si vous le souhaitez, vous pouvez faire le Moniteur ID plus lisible par l'homme avant de continuer.", + "IdentityText2": "Vous pouvez dupliquer l'écran en modifiant le Moniteur ID , puis appuyez sur save. Vous ne peut pas utiliser l'ID d'un moniteur qui existe déjà ou qu'il permettra d'économiser plus que surveiller les informations de base de données.", + "Idle": "Inactif", + "Image Height": "La Hauteur De L'Image", + "Image Location": "Emplacement de l'Image de Chemin d'accès Absolu ou laissez le champ vide pour utiliser mondiale", + "Image Position": "La Position De L'Image", + "Image Width": "La Largeur De L'Image", + "Import": "L'importation", + "Import Monitor Configuration": "L'Importation De Configuration Du Moniteur De", + "ImportMonitorConfigurationText": "En faisant cela, vous overrwrite toutes les modifications ne sont pas enregistrées. Les modifications importées ne sera appliquée que lorsque vous appuyez sur Enregistrer.", + "ImportMultiMonitorConfigurationText": "En faisant cela, vous overrwrite tous les moniteurs avec des Id existant dans le fichier d'importation.", + "In": "Dans", + "Incorrect Settings Chosen": "Des Paramètres Incorrects Choisi", + "Indifference": "L'indifférence", + "Input": "Entrée", + "Input Feed": "Entrée D'Alimentation", + "Input Flags": "Entrée Des Drapeaux", + "Input Selector": "Sélecteur D'Entrée", + "Input Settings": "Les Paramètres D'Entrée", + "Input Type": "Type D'Entrée", + "InputText1": "Cette section indique Shinobi comment utiliser un flux. Pour des performances optimales, essayez de régler votre appareil photo les réglages internes. Trouvez les options suivantes et de les définir comme illustré. Pour trouver votre appareil photo vous pouvez utiliser le construit en ONVIF Scanner de Shinobi. Certaines caméras ONVIF nécessitent l'utilisation d'un outil de gestion pour modifier leurs paramètres internes. Si vous ne trouvez pas votre appareil, vous pouvez essayer ONVIF le Gestionnaire de Périphériques de Windows.", + "InputText2": "
  • Framerate (FPS) : Haut : 10 - 15 FPS, Faible : 2 à 5 FPS
  • I-frame interval : 80
  • Taux de bits Type : CBR (Constant Bit rate)
  • Débit binaire : entre 256kbps - 500kbps
", + "InputText3": "Si vous avez besoin d'aide pour déterminer ce type d'entrée de votre appareil photo vous pouvez prendre un coup d'oeil à la Caméra Liste d'URLs sur le Shinobi site web.", + "Invalid JSON": "Invalid JSON", + "InvalidJSONText": "Veuillez vous assurer que c'est une chaîne JSON valide pour les Shinobi de configuration du moniteur.", + "JPEG": "JPEG", + "JPEG (Auto Enables JPEG API)": "JPEG (Auto Permet JPEG API)", + "JPEG API": "JPEG API Instantané (cgi-bin)", + "JPEG Error": "JPEG Erreur", + "JPEG Mode": "Le Mode JPEG", + "JPEGErrorText": "Il y avait un problème dans l'obtention de données de votre appareil photo.", + "LDAP": "LDAP", + "LDAP Success": "LDAP Succès", + "LDAP User Authenticated": "LDAP de l'Utilisateur Authentifié", + "LDAP User is New": "Utilisateur LDAP est Nouveau", + "Leave blank for random.": "Laissez vide pour aléatoire.", + "Leave blank for unlimited": "Laissez vide pour un nombre illimité de", + "Left": "Gauche Adresse URL", + "Left Stop": "Butée gauche, Adresse URL", + "Less Than": "Moins De", + "Less Than or Equal to": "Inférieure ou Égale à", + "Like": "Comme", + "Limited": "Limitée", + "Link Shinobi": "Lien Shinobi", + "Lisence Plate Detector": "Lisence Détecteur De Plaque", + "List Toggle": "Liste De Bascule", + "Live Stream Toggle": "Live Stream De La Bascule", + "Live View": "Vue En Direct", + "Local": "Local", + "Log Level": "Le Niveau De Journal", + "Log Signal Event": "Journal du Signal d'Événements côté Client seulement", + "Logging": "La journalisation", + "Login": "Connexion", + "Logout": "Déconnexion", + "Logs": "Les journaux", + "Loop Stream": "Boucle De Flux", + "MB": "MO", + "MJPEG": "MJPEG", + "MP4 (copy, libx264, libx265)": "MP4 (copie, libx264, libx265)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)", + "MPEG-DASH (includes Audio)": "MPEG-DASH (Audio)", + "MailError": "MAIL d'ERREUR : impossible d'envoyer des e-mail, Vérifiez conf.json. En ignorant toutes les fonctionnalités en s'appuyant sur l'envoi.", + "Main": "Principal", + "Male": "Mâle", + "Manual": "Manuel", + "Map": "Carte", + "Matches": "Matchs", + "Max Latency": "Max Latence", + "Max Number of Cameras": "Le Nombre maximum de Caméras", + "Max Storage Amount": "Max de la Quantité de Stockage en mo", + "Mode": "Mode", + "Monitor": "Moniteur", + "Monitor Added by user": "Moniteur Ajoutés par l'utilisateur.", + "Monitor Capture Rate": "Surveiller les Taux de Capture (FPS)", + "Monitor Groups": "La Surveillance De Groupes", + "Monitor ID": "Moniteur ID", + "Monitor Idling": "Surveiller La Marche Au Ralenti", + "Monitor Name": "Nom De Moniteur", + "Monitor Settings": "Paramètres Du Moniteur", + "Monitor Stopped": "Moniteur Arrêté", + "Monitor Updated by user": "Surveiller les mises à Jour par l'utilisateur.", + "Monitor mode changed": "Le mode moniteur changé", + "Monitor mode is already": "Le mode Monitor est déjà", + "Monitor or Key does not exist.": "Le moniteur ou la Clé n'existe pas.", + "MonitorIdlingText": "Surveiller la session a été commandé au ralenti.", + "MonitorStoppedText": "Surveiller la session a été ordonné d'arrêter.", + "Monitors": "Les moniteurs", + "Monitors per row": "Surveille par ligne de Montage", + "Monitors to Copy to": "Les moniteurs de Copie à", + "Montage": "Montage", + "Motion GUI": "Motion GUI", + "Motion Meter": "Motion Compteur", + "Name": "Nom", + "New Authentication Token": "Nouveau Jeton D'Authentification", + "New Monitor": "Nouveau Moniteur", + "No": "Pas de", + "No Audio": "Pas D'Audio", + "No Data": "Pas De Données", + "No Events found for this video": "Aucun événement trouvé pour cette vidéo", + "No Group with this key exists": "Pas de Groupe avec cette clé existe", + "No Monitor Exists with this ID.": "Pas de Moniteur Existe à cet ID.", + "No Monitor Found, Ignoring Request": "Pas De Moniteur Trouvé, En Ignorant La Demande", + "No Monitors Selected": "Pas De Moniteurs Sélectionnés", + "No Rotation": "Pas De Rotation", + "No Videos Found": "Pas De Vidéos Trouvées", + "No such file": "Pas de tel fichier", + "NoMotionEmailText1": "Pas de Mouvement pour", + "NoMotionEmailText2": "Il n'y a pas été de tout mouvement détecté sur l'appareil photo pour", + "NoVideosFoundForDateRange": "Pas de Vidéos trouvées dans cette plage de dates. Essayez de définir la date de début de la plus en arrière.", + "Noise Filter": "Filtre De Bruit", + "Not Authorized": "Pas Autorisé", + "Not Connected": "Pas Connecté", + "Not Equal to": "Pas Égal à", + "Not In": "Pas Dans", + "Not Matches": "Pas De Matchs", + "Not Permitted": "Pas Autorisés", + "Not Saved": "Pas Enregistrées", + "Not an Administrator Account": "Pas un Compte d'Administrateur", + "NotAuthorizedText1": "Pas Autorisé, Soumettre commande init avec \"auth\",\"ke\", et \"uid\"", + "Notes": "Notes", + "NotesPlacholder": "Les commentaires que vous voulez quitter pour ce caméras de paramètres.", + "Number of Days to keep": "Nombre de Jours de conservation", + "ONVIF": "ONVIF", + "ONVIF Scanner": "ONVIF Scanner", + "ONVIFnote": "Découvrez ONVIF appareils sur les réseaux à l'extérieur de votre propre ou la laisser vide pour analyser votre réseau actuel.
Nom d'utilisateur et le Mot de passe peut être laissé en blanc.", + "Object": "Objet", + "Object Tag": "Balise Object", + "OpenCV Cascades": "OpenCV Cascades", + "Options": "Options", + "Order Streams": "Afin De Ruisseaux", + "Output Method": "Méthode De Sortie", + "Password": "Mot de passe", + "Password Again": "Mot De Passe À Nouveau", + "Passwords don't match": "Les mots de passe ne correspondent pas", + "Paste JSON here.": "Coller JSON ici.", + "Path": "Chemin", + "Permissions": "Les autorisations", + "Please Wait for Completion": "Veuillez Attendre la fin, Selon le nombre de fichiers sélectionnés, cela peut prendre un certain temps. Actualiser pour vérifier de nouveau.", + "Points": "Des Points Lors de l'ajout de points de cliquer sur le bord du polygone.", + "Pop": "Pop", + "Port": "Port", + "Pose": "Poser", + "Poseidon": "Poseidon", + "Position X": "Position X", + "Position Y": "Position Y", + "Power Video Viewer": "La Puissance Du Visualiseur Vidéo", + "Power Viewer": "Visionneuse De L'Alimentation", + "Preferences": "Préférences", + "Preset": "Preset", + "Preview": "Aperçu", + "Probe Size": "Longueur De La Sonde", + "Process Crashed for Monitor": "Le processus s'est Écrasé pour Surveiller", + "Process Unexpected Exit": "Processus Inattendu De Sortie", + "Profile": "Profil", + "Quality": "La qualité de l' 1 est Élevée, 23 est Faible", + "Query": "Requête", + "RAM": "RAM", + "RTMP Stream": "Flux RTMP", + "RTMP Stream Flags": "Flux RTMP Drapeaux", + "RTSP": "RTSP", + "RTSP Transport": "RTSP de Transport", + "Range or Single": "Gamme ou Seul", + "Rate": "Taux (FPS)", + "Raw": "Raw", + "Raw H.264 Stream": "Raw H. 264 Flux", + "Recommended": "Recommandé", + "Record": "Enregistrement", + "Record File Type": "Enregistrement De Type De Fichier", + "Record Height": "Record De Hauteur", + "Record Video Filter": "Enregistrement Vidéo De Filtre", + "Record Width": "Enregistrement De Largeur", + "Recording": "Enregistrement", + "Recording FPS": "L'enregistrement de FPS", + "Recording FPS Change on Start": "Enregistrement FPS Changement sur Démarrer", + "Recording Flags": "L'Enregistrement Des Drapeaux", + "Recording Segment Interval": "Enregistrement Segment de l'Intervalle en minutes", + "Recording Timeout": "L'enregistrement de Délai d'attente en Minutes", + "Recording Timestamp": "L'Enregistrement D'Horodatage", + "Recording Watermark": "Enregistrement Filigrane", + "RecordingText": "Il est recommandé que vous définissez Enregistrement de Type de Fichier pour WebMMP4 et Vidéo Codec pour libvpxcopie ou libx264 parce que votre Type d'Entrée est définie sur .", + "Refresh List of Cascades": "Actualiser la Liste des Cascades", + "Region Editor": "Région De L'Éditeur", + "Region Name": "Nom De La Région", + "RegionNote": "Les Points ne sont enregistrées que lorsque vous appuyez sur Enregistrer sur les Paramètres du Moniteur de la fenêtre.", + "Regions": "Les régions", + "Remember Me": "Se Souvenir De Moi", + "Request": "Demande", + "Reset Timer": "Réinitialiser La Minuterie", + "Restart": "Redémarrer", + "Restart CRON": "Redémarrage du CRON", + "Restart Core": "Le Redémarrage De Base", + "Restarting Process": "Le Redémarrage Du Processus De", + "Retry Connection": "Nouvelle tentative de Connexion Nombre de fois que le droit à l'échec", + "Retrying...": "Réessayer...", + "Right": "Droit de l' Adresse URL", + "Right Stop": "Droit d'Arrêter Adresse URL", + "Rotate": "Faites tourner", + "Save": "Enregistrer", + "Save Directory": "Répertoire De Sauvegarde", + "Save Events to SQL": "Enregistrer les Événements dans le SQL", + "Save Frames to Events": "D'enregistrer les Images des Événements", + "Save Log in SQL": "Enregistrer le Journal dans SQL Cela peut se remplir rapidement.", + "Save as": "Enregistrer sous", + "Saved Filters": "Enregistré Filtres", + "Scan Settings": "Paramètres De Numérisation", + "Search": "Recherche", + "Search Base": "La Base De Recherche", + "Search Filter": "Filtre De Recherche", + "Secure": "Sécurisé", + "Send Frames": "Envoyer des Images Pousser images à analyser", + "Separate with commas, no spaces": "Séparés par des virgules, sans espace", + "Server URL": "URL du serveur", + "Set to Watch Only": "Mis à Regarder Seulement", + "Settings": "Paramètres", + "Settings Changed": "La Modification Des Réglages", + "SettingsChangedText": "Vos paramètres sont enregistrés et appliqués. Certains paramètres peuvent nécessiter une actualisation de cette page.", + "Shinobi": "Shinobi", + "Shinobi Streamer": "Shinobi Streamer", + "Show Logs": "Afficher Les Journaux D'", + "Show Regions of Interest": "Montrer les Régions d'Intérêt", + "Show Stream HUD": "Afficher les Flux de PALETTE", + "Silent": "Silencieux", + "Simple": "Simple", + "Size (mb)": "Taille (mo)", + "Snapshot": "Instantané", + "Snapshot Flags": "Instantané De Drapeaux", + "Snapshots": "Instantanés", + "Sort By": "Trier Par", + "Start": "Démarrer", + "Start Recording": "Démarrer L'Enregistrement", + "Start Time": "Heure De Début", + "Started": "Commencé", + "Status Indicator": "Indicateur De L'État De", + "Stop": "Arrêter", + "Stop URL": "Arrêter URL", + "Storage Location": "Emplacement De Stockage", + "Stream": "Flux", + "Stream Channel": "Canal De Flux De Données", + "Stream Flags": "Flux De Drapeaux", + "Stream Key": "Flux De Clé", + "Stream Timestamp": "Flux D'Horodatage", + "Stream Type": "Type De Flux", + "Stream Watermark": "Flux De Filigrane", + "Stream to YouTube": "Stream sur YouTube", + "Stream to YouTube Flags": "Stream sur YouTube Drapeaux", + "StreamText": "

Cette section permettra de désigner le flux primaire, de méthode et de ses paramètres. Ce flux sera affiché dans le tableau de bord. Si vous choisissez d'utiliser HLS, JPEG, MJPEG, alors vous pouvez consommer du courant à travers d'autres programmes.

JPEG flux essentiellement désactive le principal cours d'eau et les utilisations de l'instantané bin pour obtenir des images.

", + "Streamer": "Streamer", + "Streams": "Flux", + "Superuser": "Superutilisateur", + "Superuser Logs": "Superuser Journaux", + "Switch on for Still Image": "Interrupteur pour Toujours à l'Image", + "System": "Système", + "TCP": "TCP", + "TV Channel": "Chaîne de TÉLÉVISION", + "TV Channel Group": "Chaîne de TÉLÉVISION du Groupe", + "TV Channel ID": "Chaîne de TÉLÉVISION ID", + "Text Box Color": "Texte De La Boîte De Couleur", + "Text Color": "La Couleur Du Texte", + "Themes": "Thèmes", + "There are no monitors that you can view with this account.": "Il n'y a pas les moniteurs que vous pouvez afficher avec ce compte.", + "Time-lapse": "Time-lapse", + "Time-lapse Tool": "Time-lapse de l'Outil", + "Timeout": "Timeout", + "Timeout Reset on Next Motion": "Délai de Réinitialisation sur le Prochain Mouvement", + "Toggle Sidebar": "Basculer La Barre Latérale", + "Top Left": "En Haut À Gauche", + "Top Right": "En Haut À Droite", + "Traditional (Watch-Only, Includes Buffer)": "Traditionnel (Watch-Seulement, Comprend Tampon)", + "Traditional Recording": "Traditionnelle Enregistrement", + "Trigger Record": "Déclencheur D'Enregistrement", + "Trigger Successful": "Déclencheur De Succès", + "UDP": "UDP", + "URL": "URL", + "URL Stop Timeout": "URL Arrêter Délai Run stop URL après X millisecondes", + "US": "NOUS", + "Unable to Launch": "Impossible de Lancer", + "UnabletoLaunchText": "Veuillez enregistrer le nouveau moniteur en premier. Tentez ensuite de lancer la région de l'éditeur.", + "Uniform": "Uniforme", + "Up": "Jusqu' Adresse URL", + "Up Stop": "D'Arrêter Adresse URL", + "Update": "Mise à jour", + "Update to Development": "Mise à jour pour le Développement", + "Update to Master": "Mise à jour de Maître", + "Use Built-In": "Utilisez La Fonction De", + "Username": "Nom d'utilisateur", + "Value": "Valeur", + "Video": "Vidéo", + "Video Bit Rate": "Le Débit Binaire Vidéo", + "Video Codec": "Codec Vidéo", + "Video Filter": "Filtre Vidéo", + "Video Finished": "Vidéo Fini", + "Video Length (minutes) and Motion Count per video": "Durée de la vidéo (en minutes) et le Mouvement Comte par vidéo", + "Video Limit": "Vidéo Limite", + "Video Record Rate": "Vidéo vitesse d'Enregistrement (IPS)", + "Video Status": "État De La Vidéo", + "Video and Time Span (Minutes)": "La vidéo et la Durée (en Minutes)", + "Videos": "Vidéos", + "Videos List": "Liste Des Vidéos", + "Warning": "Avertissement", + "Watch": "Regarder", + "Watch Only": "Regarder Seulement", + "WebDAV": "WebDAV", + "WebM (libvpx)": "WebM (libvpx)", + "Webdav Error": "Webdav Erreur", + "WebdavErrorText": "Impossible d'enregistrer. Avez-vous rendre l'appareil dossiers à l'intérieur de votre choisi répertoire de sauvegarde?", + "Webhook": "Webhook", + "Webhook URL": "Webhook URL", + "Websocket": "Websocket", + "Websocket Connected": "Websocket Connecté", + "Websocket Disconnected": "Websocket Déconnecté", + "Width": "Largeur", + "Yes": "Oui", + "Zoom In": "Zoom Dans l' Adresse URL", + "Zoom In Stop": "Zoom Arrêter Adresse URL", + "Zoom Out": "Zoom Adresse URL", + "Zoom Out Stop": "Zoom Arrêter Adresse URL", + "a day": "un jour", + "a few seconds": "quelques secondes", + "a minute": "une minute", + "a month": "un mois", + "a year": "un an", + "aac": "aac", + "aac (Default)": "aac (par Défaut)", + "ac3": "ac3", + "ago": "il y a", + "an hour": "une heure", + "bindDN": "bindDN", + "blankPassword": "Laissez le champ vide pour garder le même mot de passe", + "clientStreamFailedattemptingReconnect": "Côté Client ctream échec de la vérification, d'essayer de se reconnecter.", + "confirmDeleteFilter": "Voulez-vous supprimer ce filtre? Vous ne pouvez pas le récupérer.", + "copy": "copie", + "cuvid": "cuvid (NVIDIA NVENC)", + "days": "jours", + "dropBoxSuccess": "Succès! Les fichiers enregistrés sur votre Dropbox.", + "dxva2": "dxva2 (Vidéo DirectX, Windows)", + "flv": "flv", + "for Global Access": "pour l'Accès Mondial", + "h264_cuvid": "H. 264 CUVID", + "h264_nvenc": "H. 264 NVENC (NVIDIA HW Accel)", + "h264_qsv": "H. 264 (Quick Sync Video)", + "h264_vaapi": "H. 264 VA-API (Intel HW Accel)", + "hevc_cuvid": "H. 265 CUVID", + "hevc_nvenc": "H. 265 NVENC (NVIDIA HW Accel)", + "hevc_qsv": "H. 265 (Quick Sync Video)", + "hevc_vaapi": "H. 265 VA-API (Intel HW Accel)", + "hours": "heures", + "hwaccel": "L'Accélération Du Moteur", + "hwaccel_device": "HWAccel Appareil", + "hwaccel_vcodec": "Décodeur Vidéo", + "in": "dans", + "in Days": "dans les Jours", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis (par Défaut)", + "libvpx (Default)": "libvpx (par Défaut)", + "libvpx-vp9": "libvpx-vp9", + "libx264": "libx264", + "libx264 (Default)": "libx264 (par Défaut)", + "libx265": "libx265", + "minutes": "minutes", + "mjpeg_cuvid": "MJPEG CUVID", + "modifyVideoText1": "La méthode n'existe pas. Assurez-vous que la dernière valeur de l'URL n'est pas vide.", + "monSavedButNotCopied": "Votre moniteur a été sauvé, mais pas copié sur un autre moniteur.", + "monitorEditFailedMaxReached": "Votre compte a atteint le nombre maximum de caméras qui peuvent être créés. Parler à un administrateur si vous souhaitez que cela a changé.", + "monitorEditText1": "Des Données non valides, Vérifiez la validité de l'importation de la chaîne.", + "monitorEditText2": "Non Valide Les Détails De La Chaîne. Vérifiez pour voir c'est une chaîne JSON et non pas un objet normal d'être passé.", + "monitorGetText1": "demande incomplète, supprimer le dernier slash dans l'URL ou mettre valeur acceptable.", + "months": "mois", + "mpeg2_qsv": "MPEG2 (Quick Sync Video)", + "mpeg4_cuvid": "MPEG4 CUVID", + "noSpecialCharacters": "Pas d'espaces ni de caractères spéciaux.", + "notPermitted1": "Cette action n'est pas autorisée par l'administrateur de votre compte\".", + "on": "sur", + "on Error": "en cas d'Erreur", + "powerVideoEventLimit": "Vous avez une grande manifestation limite. Êtes-vous sûr que vous voulez faire cette demande?", + "qsv": "qsv", + "startUpText0": "vérification de la taille pour les vidéos", + "startUpText1": "fin de la vérification de la taille pour les vidéos", + "startUpText2": "tous les utilisateurs vérifiés, attendre pour fermer les fichiers ouverts et supprimer les fichiers de plus de limite de l'utilisateur", + "startUpText3": "d'attente pour donner inachevé vidéo de vérifier un certain temps. 3 secondes.", + "startUpText4": "départ tous les moniteurs ensemble pour regarder et enregistrer", + "startUpText5": "Shinobi est prêt.", + "superAdminText": "\"super.json\" n'existe pas. Veuillez renommer \"super.de l'échantillon.json\" à \"super.json\".", + "total": "total", + "updateKeyText1": "\"updateKey\" est manquant à partir de \"conf.json\", ne peut pas faire les mises à jour de cette façon jusqu'à ce que vous l'ajouter.", + "updateKeyText2": "\"updateKey\" est incorrecte.", + "vaapi": "vaapi (VA-API)", + "vda": "vda (Apple VDA l'Accélération Matérielle)", + "vdpau": "vdpau", + "videotoolbox": "videotoolbox", + "vp8_cuvid": "VP8 NVENC (NVIDIA HW Accel)", + "vp8_qsv": "VP8 (Quick Sync Video)", + "vp9_cuvid": "VP9 NVENC (NVIDIA HW Accel)", + "years": "ans" +} diff --git a/languages/ja.json b/languages/ja.json new file mode 100644 index 0000000..d6e692a --- /dev/null +++ b/languages/ja.json @@ -0,0 +1,496 @@ +{ + "\"No Motion\" Detector": "\"動き\"の検出器", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "180 Degrees": "180度", + "2-Factor Authentication": "2要素認証", + "90 Clockwise": "時計回りに90", + "90 Clockwise and Vertical Flip": "90右回転、上下反転", + "90 Counter Clockwise and Vertical Flip (default)": "90反時計方向に回し、上下反転(デフォルト)", + "API": "API", + "API Key Added": "APIキーの追加", + "API Key Deleted": "APIキーの削除", + "API Keys": "APIキー", + "APIKeyAddedText": "にお使いいただけキーです。", + "APIKeyDeletedText": "キーが削除されました。 ではなくなります。", + "ASC": "ASC", + "Account Info": "アカウント情報", + "AccountEditText1": "な編集できるようになります。 リフレッシュページの場合は問題が続きます。", + "Accounts": "座", + "Action for Selected": "行動選択", + "Add": "追加", + "Add Monitor": "追加モニター", + "Add New": "新規追加", + "Admin": "Admin", + "Advanced": "先進", + "Again": "再", + "All Monitors": "すべてのモニター", + "All Monitors and Privileges": "すべての監視および権限", + "All Warnings": "すべての警告", + "Allow Next Command": "を次のコマンド ", + "Allow Next Email": "を次のメール に分", + "Allow Next Trigger": "を次のトリガ をミリ秒単位", + "Allowed IPs": "可IPs", + "Analyzation Duration": "解析期間", + "Archive": "アーカイブ", + "Audio Codec": "オーディオコーデック", + "Authenticate": "認証", + "Auto": "オート", + "Autosave": "ぜ", + "Base64 over Websocket": "Base64上Websocket", + "Bottom Left": "左下", + "Bottom Right": "右下", + "Browser Console Log": "ブラウザコンソールのログ", + "CPU": "CPU", + "CPU indicator will not work. Continuing...": "CPU表示できません。 続きを---", + "CSS": "CSS スタイルダッシュボードです。", + "Calendar": "カレンダー", + "Camera Password": "カメラのパスワード", + "Camera Username": "カメラのユーザー名", + "Camera is not recording": "カメラは記録", + "CameraNotRecordingText": "設定の場合は相容れないものがある。 チェックエンコーダです。 再...", + "Can Control Monitors": "を制御できるモニター", + "Can Delete Videos": "で削除できる動画", + "Can Delete Videos and Events": "削除が可能でのビデオやイベント", + "Can Edit Monitor": "編集できるモニター", + "Can Get Logs": "でログ", + "Can Get Monitors": "できるモニター", + "Can View Monitor": "できるビューモニター", + "Can View Snapshots": "でスナップショット", + "Can View Streams": "での流れ", + "Can View Videos": "できるビュー動画", + "Can View Videos and Events": "できるビュービデオやイベント", + "Can't Connect": "ですね", + "Center": "センター のURLアドレス", + "Chat on Discord": "チャット上の不和", + "Check": "チェック", + "Check Signal Interval": "チェック信号の間隔 ", + "Check for Motion First": "チェックモーションの最初", + "Close": "近", + "Closed": "閉鎖", + "Command": "コマンド", + "Command on Trigger": "コマンドをトリガー", + "Complete Stream URL": "完全なストリームURL", + "Confirm": "確認", + "Connected": "接続", + "Connection Type": "接続タイプ", + "Control": "制御", + "Control Error": "制御エラー", + "ControlErrorText1": "制御が有効にならない", + "Controllable": "制御可能", + "Country of Plates": "国板", + "Counts of Motion": "カウントの運動", + "Current": "現在の", + "Currently viewing": "現在閲覧", + "Custom": "カスタム", + "Custom Base URL": "カスタムベースURL は空欄で結構使ホストのURL", + "DB Lost.. Retrying..": "データベース失われた..再試行す。", + "DESC": "お得に!", + "Dashboard": "ダッシュボード", + "Dashboard Language": "ダッシュボードの言語", + "Dashcam": "Dashcam", + "Dashcam (Streamer v2)": "Dashcam(ストリーマv2)", + "Date Range": "日付の範囲", + "Debug": "デバッグ", + "Default": "デフォルト", + "Delete": "削除", + "Delete Filter": "削除フィルター", + "Delete Matches": "チ削除", + "Delete Monitor": "モニター削除", + "Delete Motionless Video": "削除静止画", + "Delete Motionless Videos (Record)": "削除静止画録画", + "Delete Selected Videos": "削除選択した動画", + "Delete Video": "ビデオ削除", + "Delete selected": "削除を選択", + "DeleteMonitorText": "い削除したいことがわか? はできません回復します。 ファイルのためにこのIDをファイルシステムです。 を選択の場合は再現モニターで同じIDのビデオやイベントが可視のダッシュボードです。", + "DeleteSelectedVideosMsg": "に削除しますこれらの動画です。 はできません回復しています。", + "DeleteVideoMsg": "に削除しますこの動画です。 はできません回復します。", + "Deleted": "削除", + "Detect Objects": "検出物体 以下参照", + "Detector": "検出器", + "Detector Flags": "検出フラグ", + "Detector Rate": "検出率 (FPS)", + "DetectorText": "

の幅と高さのボックス表示設定すべきであるし640x480以下になりました。 この最適化とともに、これまでの読取速度のフレームです。

", + "Disable Night Vision": "除夜のビジョン のURLアドレス", + "Disable Nightvision": "Disable Nightvision", + "Disabled": "障害者", + "Documentation": "文書", + "Don't show this anymore": "いこう", + "Double Quote Directory": "ダブルクォートディレクトリ の一部のディレクトリしています。 この場合クラッシュカメラです。", + "Down": "下 のURLアドレス", + "Down Stop": "ダウン停止 URLアドレス", + "Download": "ダウンロード", + "EU": "EU", + "Edit": "編集", + "Email": "メール", + "Email Details": "メールの詳細", + "Email on No Motion": "メールでの\"動き\"", + "Email on Trigger": "メールでのトリガー のメールのページ内移動用のメニュー口座のログインアドレスです。", + "Enable Night Vision": "するナイトビジョン のURLアドレス", + "Enable Nightvision": "をNightvision", + "Enabled": "有効な", + "End": "終了", + "End Time": "終了時間", + "Ended": "終了", + "Enlarge": "拡大", + "Enter this code to proceed": "コードを入力して登録へ", + "Equal to": "等しい", + "Error Connecting": "接続エラー", + "Event": "イベント", + "Event Limit": "イベントに制限", + "EventText1": "起動イベント", + "EventText2": "はメールに画像ファイルにアクセスできないか、または", + "Events": "イベント", + "Example": "例", + "Execute Command": "コマンドを実行し", + "Executed": "実行され", + "Export": "輸出", + "FFmpegCantStart": "Gpartedっ開始", + "FFmpegCantStartText": "の記録エンジン本カメラが起動しません。 あかカメラの設定をします。 の場合はログ以外にこだ後の 課題を Githubです。", + "FFmpegTip": "FFprobeが簡単なマルチメディアの流れの測定を行いました。 利用できる出力のすべての種類に関する情報の入力を含む期間には、フレームレートは、フレームサイズ等", + "FFprobe": "プローブ", + "FactorAuthText1": "このコードのみで活躍する15分間とさせていただきます。 場合は再度ログインしますタイマーをリセットされます15分と同じコードです。", + "Fatal": "致命的な", + "Fatal Maximum Reached": "死亡の最大に達し、停止ます。", + "FatalMaximumReachedText": "JPEGエラー致命的にするかもしれない。", + "Feed-in Image Height": "飼料-画像の高さ", + "Feed-in Image Width": "飼料-画像の幅", + "Fields cannot be empty": "分野できない空", + "File Not Exist": "ファイルが存在しない", + "File Not Found": "ファイルが見つかりません", + "File Type": "ファイルの種類", + "FileNotExistText": "登録できない不existantファイルです。 何かが分かります。", + "Filename": "ファイル名", + "Filesize": "Filesize", + "Filter ID": "フィルタのID", + "Filter Matches": "フィルターの試合", + "Filter Name": "フィルター名", + "FilterMatchesText1": "このフィルタを満たす条件です。", + "FilterMatchesText2": "動画で見つかります。", + "Filters": "フィル", + "Filters Updated": "フィ更新", + "FiltersUpdatedText": "ご変更して保存され、適用されます。", + "Find Where": "見所", + "Fix": "Fix", + "Fix Video": "修正ビデオ", + "FixVideoMsg": "したい着この動画です。 元に戻せませんこの行動します。", + "Font Path": "フォントのパス", + "Font Size": "文字サイズ", + "Force Port": "力ポート", + "Found Devices": "たデバイス", + "Frame Rate": "フレームレート (FPS)", + "Full Frame Detection": "フルフレーム検出", + "Fullscreen": "フルスクリーン", + "Greater Than": "以上", + "Greater Than or Equal to": "以上", + "Group Key": "パブリックグループ", + "Group Name": "グループ名", + "Grouping": "グループ化 ", + "H.264 / H.265 / H.265+": "H.264/H.265/H.265 ", + "HLS (.m3u8)": "HLS(します。m3u8)", + "HLS (includes Audio)": "HLS(オーディオ)", + "HLS Audio Encoder": "HLSオーディオエンコーダ", + "HLS List Size": "HLSリストのサイズ", + "HLS Preset": "HLSプリセット", + "HLS Segment Length": "HLSセグメント長 ", + "HLS Video Encoder": "HLSビデオエンコーダ", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "Height": "高さ", + "Help": "助", + "Hide List": "Hide一覧", + "Hide Notes": "Hide注", + "Host": "ホスト", + "Hotswap Modes (Watch-Only)": "Hotswapモード時のみ)", + "How to Record": "その記録", + "IP Address": "IPアドレス", + "Identity": "ティ", + "IdentityText1": "このシステムを特定のデータをこのストリームです。 大きさを変えることはできませんの モニタIDを 一度押すと保存されます。 したい場合はしないように注意してください モニタID をより人間が読める形式だけます。", + "IdentityText2": "また複数のモニターを変更することにより、 モニタID を押すと保存されます。 す 利用のIDのモニターするにあたりまえるモニターのデータベースの情報です。", + "Idle": "アイドル", + "Image Height": "画像の高さ", + "Image Location": "画像の位置 を絶対パスまたは空欄で結構使用グローバル", + "Image Position": "画像の位置", + "Image Width": "画像の幅", + "Import": "輸入", + "Import Monitor Configuration": "輸入モニターの設定", + "ImportMonitorConfigurationText": "そうするとoverrwriteの変更は、現在保存されません。 輸入の変化のみに適用される場合を押すと 保存します。", + "In": "に", + "Incorrect Settings Chosen": "誤った設定を選択", + "Indifference": "無関心", + "Input": "入力", + "Input Flags": "入力フラグ", + "Input Type": "入力タイプ", + "InputText1": "これ忍どのように消費するストリームです。 最適な性能チューニングしてみカメラの内部設定します。 として以下のようなオプションセットとして表示します。 ディスカメラで利用できます 内蔵ONVIFスキャナー の向きを変えて走り出した。 一部のONVIFカメラの使用を必要とする管理ツールの変更を内部設定します。 できない場合は空のカメラをお試しいただ ONVIFデバイスマネージャー Windowsます。", + "InputText2": "
  • Framerate(FPS): 高さ:10-15FPS、低:2-5FPS
  • Iフレーム間隔: 80
  • ビットレート: CBR(定ビットレート)
  • ビットレート: 間256kbps-500kbps
", + "InputText3": "困ったときにはコーヒーに飽きたら寿司にどのような入力インターネットにアクセスでカメラをご覧になることができる カメラのUrlリスト の商品につけられます。", + "Invalid JSON": "無効なJSON", + "InvalidJSONText": "ご確認くださいここは有効なJSON文字列のための商品につけられたモニターを設定します。", + "JPEG": "JPEG", + "JPEG (Auto Enables JPEG API)": "JPEG(自動車をJPEG API)", + "JPEG API": "JPEG APIの スナップショット(cgi-bin)", + "JPEG Error": "JPEGエラー", + "JPEG Mode": "JPEGモード", + "JPEGErrorText": "が課題となった取得データからカメラです。", + "Leave blank for random.": "空白の場合ランダムです。", + "Left": "左 のURLアドレス", + "Left Stop": "左停 URLアドレス", + "Less Than": "以上", + "Less Than or Equal to": "以下の", + "Like": "のように", + "Lisence Plate Detector": "ライセンプレート検出器", + "List Toggle": "リストを切り替え", + "Live Stream Toggle": "ライブストリームを切り替え", + "Live View": "ライブビュー", + "Local": "地", + "Log Level": "ログレベル", + "Log Signal Event": "ログ信号のイベント クライアント側のみ", + "Logging": "ログイン", + "Login": "ログイン", + "Logout": "アウト", + "Logs": "ログ", + "MB": "MB", + "MJPEG": "MJPEG", + "MP4 (copy, libx264, libx265)": "MP4(コピー、libx264は、libx265)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4(い。mp4ます。ts)", + "MailError": "メールエラーがない送信メールは、チェックconfです。jsonです。 飛び他の特徴に依存のメーリングします。", + "Matches": "試合", + "Max Storage Amount": "最大の貯蔵量を 、メガバイト", + "Mode": "モード", + "Monitor": "モニター", + "Monitor Added by user": "モニター追加によりユーザーです。", + "Monitor Capture Rate": "モニター捕捉率 (FPS)", + "Monitor Groups": "モニター集団", + "Monitor ID": "モニタID", + "Monitor Idling": "モニターアイドリング", + "Monitor Name": "モニタ名称", + "Monitor Settings": "モニタ設定", + "Monitor Stopped": "モニターを停止", + "Monitor Updated by user": "モニターを更新します。", + "Monitor mode changed": "モニタモード変更", + "Monitor mode is already": "モニターモードで", + "Monitor or Key does not exist.": "モニターやキーが存在しません。", + "MonitorIdlingText": "モニターセッションが命じられた。", + "MonitorStoppedText": "モニターセッションの中止を命じます。", + "Monitors": "モニター", + "Monitors per row": "モニター当行 のためのモンタージュ", + "Montage": "モンタージュ", + "Motion GUI": "動GUI", + "Motion Meter": "運動メーター", + "Name": "名称", + "No": "No", + "No Audio": "オーディオ", + "No Data": "データなし", + "No Events found for this video": "イベントはありませんがこの動画", + "No Group with this key exists": "グループはこの鍵が存在する", + "No Monitor Found, Ignoring Request": "なモニター、要請を無視して", + "No Rotation": "回転無し", + "No such file": "なファイル", + "NoMotionEmailText1": "不動", + "NoMotionEmailText2": "あなたの運動検知のためのカメラ", + "NoVideosFoundForDateRange": "ない映像がこの日付範囲から選びます。 う設定の開始日は\"まだ完全に回復してます。", + "Not Authorized": "権限がない", + "Not Connected": "接続されていない", + "Not Equal to": "と等しくない", + "Not In": "ない", + "Not Matches": "ない試合", + "Not Permitted": "許可されない", + "Not an Administrator Account": "な管理者のアカウント", + "NotAuthorizedText1": "認証されていないの提出からinitコマンド\"auth\"は、\"ke\"、\"uid\"", + "Notes": "注記", + "NotesPlacholder": "コメントするため、このカメラを設定します。", + "Number of Days to keep": "数日間の保", + "ONVIF": "ONVIF", + "ONVIF Scanner": "ONVIFのスキャナー", + "ONVIFnote": "発見ONVIFのデバイスネットワーク以外はと思われる項目に関しては、空白をスキャン現在のネットワークです。
ユーザー名とパスワードを選択することも可能です。", + "OpenCV Cascades": "OpenCVンアプリケーション", + "Order Streams": "注文の流れ", + "Output Method": "出力方法", + "Password": "パスワード", + "Password Again": "パスワードを再", + "Passwords don't match": "パスワードと一致しません", + "Paste JSON here.": "ペーストはJSONです。", + "Path": "パス", + "Permissions": "アクセス権", + "Points": "ポイント が加算ポイントをクリックの端にポリゴンです。", + "Port": "港", + "Position X": "X位置", + "Position Y": "位置Y", + "Power Video Viewer": "電動画ビューワー", + "Power Viewer": "電力ビューア", + "Preferences": "設定", + "Preset": "プリセット", + "Probe Size": "プローブサイズ", + "Process Crashed for Monitor": "工程ぶためのモニター", + "Process Unexpected Exit": "過程で予想外の出口", + "Profile": "概要", + "Quality": "品質の 1が高く、23日には低", + "Query": "クエリ", + "RAM": "RAM", + "RTSP": "RTSP", + "RTSP Transport": "RTSP輸送", + "Range or Single": "範囲またはシングル", + "Rate": "率 (FPS)", + "Record": "記録", + "Record File Type": "録音ファイルの種類", + "Record Height": "記録の高さ", + "Record Video Filter": "ビデオをフィルター", + "Record Width": "記録幅", + "Recording": "記録", + "Recording Flags": "記録フラグ", + "Recording Segment Interval": "録音のセグメント間隔 ", + "Recording Timeout": "を記録タイムアウト ", + "Recording Timestamp": "を記録タイムスタンプ", + "Recording Watermark": "録画透かし", + "RecordingText": "であることをおすすめの設定 を記録ファイルの種類WebMMP4 - ビデオコーデックlibvpxコピーまたは libx264 でご 入力タイプ に設定し ます。", + "Refresh List of Cascades": "リフレッシュリストンアプリケーション", + "Region Editor": "地域のエディタ", + "Region Name": "地域名", + "RegionNote": "ポイントのみ保存を押すと 保存モニター設定 ウインドウです。", + "Regions": "地域", + "Remember Me": "グイン情報を記憶させ", + "Reset Timer": "リセットタイマー", + "Restarting Process": "再稼働プロセスの加", + "Retry Connection": "再接続 回数許されな", + "Retrying...": "リトライ動作中に---", + "Right": "右 のURLアドレス", + "Right Stop": "右停止 のURLアドレス", + "Rotate": "回転", + "Save": "保存", + "Save Directory": "保存ディレクトリ", + "Save Events to SQL": "保存イベントへSQL", + "Save Log in SQL": "ログの保存アプリケーションで この事がございます。", + "Save as": "として保存", + "Saved Filters": "保存したフィルター", + "Scan Settings": "スキャン設定", + "Search": "検索", + "Send Frames": "送信フレーム プするフレームの解析", + "Separate with commas, no spaces": "分離をカンマ区切りで入力し、空間", + "Set to Watch Only": "設定時のみ", + "Settings": "設定", + "Settings Changed": "設定変更", + "SettingsChangedText": "設定して適用されます。", + "Shinobi": "忍", + "Shinobi Streamer": "商品につけられたストリーマ", + "Show Logs": "ショーログ", + "Silent": "黙", + "Simple": "簡単な", + "Size (mb)": "サイズ(mb)", + "Snapshot": "スナップショット", + "Snapshot Flags": "スナップショットフラグ", + "Snapshots": "スナップショット", + "Sort By": "並べ替え", + "Start": "開始", + "Start Recording": "録音を開始", + "Start Time": "開始時間", + "Started": "を開始", + "Status Indicator": "ステータスインジケータ", + "Stop URL": "停URL", + "Stream": "ストリーム", + "Stream Flags": "ストリームフラグ", + "Stream Timestamp": "ストリームにタイムスタンプ", + "Stream Type": "ストリームタイプ", + "Stream Watermark": "ストリームゾート", + "Stream to YouTube": "ストリームをYouTube", + "Stream to YouTube Flags": "ストリームをYouTube旗", + "StreamText": "

ここでは指定のストリーム出方法で設定します。 このストリームに表示されるので、ダッシュボードです。 ご利用にHLS、JPEG、MJPEGきを摂取することができ、ストリームを通じてその他のプログラムです。

使用JPEGストリームは本質的にoffのストリームを使用してスナップショットの原材料へのコンタミ防止のフレームを取得します。

", + "Streamer": "ストリーマ", + "Streams": "渓流", + "Superuser": "Superuser", + "Switch on for Still Image": "スイッチのための画像", + "TCP": "TCP", + "Text Box Color": "テキストボックスの色", + "Text Color": "テキストカラーを設定します。", + "Time-lapse": "時間", + "Time-lapse Tool": "インターバル撮ツール", + "Timeout": "タイムアウト", + "Timeout Reset on Next Motion": "タイムアウトリセットは次の運動", + "Toggle Sidebar": "サイドバーを切り替え", + "Top Left": "トップ左", + "Top Right": "トップ右", + "Trigger Record": "トリガ記録", + "Trigger Successful": "トリガー成功", + "UDP": "UDP", + "URL": "URL", + "URL Stop Timeout": "URLを停止タイムアウトの 実行を停止URLの後にXをミリ秒", + "US": "米", + "Unable to Launch": "できない開始", + "UnabletoLaunchText": "保存しておいてください新しいモニターします。 その試みを開始、地域のエディタです。", + "Up": "Up URLアドレス", + "Up Stop": "最大停止 のURLアドレス", + "Username": "ユーザー名", + "Value": "値", + "Video": "ビデオ", + "Video Codec": "ビデオコーデック", + "Video Filter": "映像フィルター", + "Video Finished": "ビデオ完成", + "Video Length (minutes) and Motion Count per video": "動画の長さ(分)運動回数の映像", + "Video Record Rate": "デジタルビデオ入出力率 (FPS)", + "Video Status": "ビデオの状況", + "Video and Time Span (Minutes)": "映時間(分)", + "Videos": "ビデオ", + "Videos List": "動画一覧", + "Watch": "腕時計", + "Watch Only": "時計のみ", + "WebDAV": "WebDAV", + "WebM (libvpx)": "WebM(libvpx)", + "Webdav Error": "Webdavエラー", + "WebdavErrorText": "登録できないます。 ただ、カメラ内のフォルダ選択保存ディレクトリのか?", + "Webhook": "Webhook", + "Webhook URL": "Webhook URL", + "Width": "幅", + "Yes": "あり", + "Zoom In": "ズーム のURLアドレス", + "Zoom In Stop": "ズーム停止 のURLアドレス", + "Zoom Out": "縮小 URLアドレス", + "Zoom Out Stop": "表示が自動的に切り替わり止め のURLアドレス", + "a day": "日", + "a few seconds": "数秒", + "a minute": "分", + "a month": "月", + "a year": "年", + "aac": "デスクトップ、エンタープライズ", + "aac (Default)": "デスクトップ、エンタープライズ(デフォルト)", + "ac3": "ac3", + "ago": "前", + "an hour": "時間", + "blankPassword": "空欄で結構いパスワード", + "calendar": "カレンダー", + "clientStreamFailedattemptingReconnect": "クライアント側ctreamチェックに失敗したとしてもう一度接続してください。", + "confirmDeleteFilter": "に削除しますこのフィルタすか? はできません回復します。", + "copy": "コピー", + "days": "日", + "dropBoxSuccess": "あなた方の成功を意味する。 ファイルをDropboxに保存されます。", + "for Global Access": "グローバルアクセス", + "hours": "時間", + "in": "に", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis(デフォルト)", + "libvpx (Default)": "libvpx(デフォルト)", + "libvpx-vp9": "libvpx-vp9", + "libx264": "libx264", + "libx264 (Default)": "libx264(デフォルト)", + "libx265": "libx265", + "minutes": "分", + "modifyVideoText1": "方法は存在しないます。 よって実行されていることを確認する最後の値はURLではない空白にします。", + "monitorEditFailedMaxReached": "アカウントの最大数のカメラが作成できます。 話管理者の体力があれば誰でも楽しめます。", + "monitorEditText1": "無効なデータを確認する有効なインポート文字列になります。", + "monitorEditText2": "無効な内容の文字列です。 確認でJSON文字列ではなく通常のオブジェクトに渡されます。", + "monitorGetText1": "不完全な要求の削除、最後のスラッシュのURLまたは許容値です。", + "months": "ヶ月", + "noSpecialCharacters": "なし空間または特殊文字です。", + "on": "月", + "on Error": "エラー時", + "startUpText0": "サイズのチェックビデオ", + "startUpText1": "末サイズをチェックビデオ", + "startUpText2": "すべてのユーザーがチェックに近いファイルを開く削除ファイルはユーザー制限", + "startUpText3": "待ちに未完成の映像チェックします。 3秒です。", + "startUpText4": "すべてのモニタ設定時記録", + "startUpText5": "忍びのご用意もあります。", + "superAdminText": "\"スーパーです。json\"は存在しない。 お名前を変更する\"スーパーです。サンプルです。json\"\"スーパーです。json\"です。", + "superAdminTitle": "世界一のスーパー管理者", + "total": "合計", + "updateKeyText1": "\"updateKey\"が\"confです。json\"になるんで更新するまでに追加します。", + "updateKeyText2": "\"updateKey\"が間違っています。", + "years": "年" +} diff --git a/languages/pt_BR.json b/languages/pt_BR.json new file mode 100644 index 0000000..34b64f4 --- /dev/null +++ b/languages/pt_BR.json @@ -0,0 +1,531 @@ +{ + "Shinobi": "Shinobi", + "superAdminTitle": "Shinobi : Super Admin", + "Login": "Entrar", + "Authenticate": "Autenticar", + "Dashboard": "Painel de Controle", + "Streamer": "Transmissor", + "Admin": "Admin", + "Superuser": "Superusuário", + "Dashcam": "Dashcam", + "Email": "E-mail", + "Username": "Usuário", + "Profile": "Perfil", + "Password": "Senha", + "Password Again": "Senha novamente", + "Remember Me": "Lembrar", + "RAM": "RAM", + "CPU": "CPU", + "on": "ligado", + "Power Viewer": "Ligar visualizador", + "Power Video Viewer": "Ligar visualizador de vídeo", + "Time-lapse": "Time-lapse", + "Montage": "Montagem", + "Accounts": "Contas", + "Settings": "Configurações", + "API": "API", + "ONVIF": "ONVIF", + "FFprobe": "Probe", + "Filters": "Filtros", + "Logs": "Logs", + "List Toggle": "Mostrar lista", + "Hide List": "Esconder Lista", + "Motion GUI": "GUI de Movimento", + "JPEG Mode": "Modo JPEG", + "Order Streams": "Ordenar transmissões", + "Hide Notes": "Esconder Notas", + "Example": "Exemplo", + "Logout": "Sair", + "Closed": "Fechado", + "Ended": "Finalizado", + "Started": "Iniciado", + "Monitor": "Monitor", + "Filename": "Nome do Arquivo", + "Size (mb)": "Tamanho (mb)", + "Watch": "Assistir", + "Download": "Baixar", + "Delete": "Deletar", + "Fix": "Corrigir", + "Zoom In": "Mais Zoom URL Address", + "Zoom Out": "Menos Zoom URL Address", + "Enable Nightvision": "Ativar Visão Noturna", + "Disable Nightvision": "Desativar Visão Noturna", + "Current": "Atual", + "Monitors": "Monitors", + "Video": "Video", + "Videos": "Videos", + "Events": "Eventos", + "Streams": "Transmissões", + "Snapshot": "Snapshot", + "Snapshots": "Snapshots", + "Date Range": "Intervalo de Data", + "Event Limit": "Limite de Evento", + "No Data": "Sem Dados", + "Live View": "Visualização ao vivo", + "Add": "Adicionar", + "Save": "Salvar", + "Close": "Fechar", + "Check": "Verificar", + "Confirm": "Confirmar", + "Enable": "Habilitar", + "Enabled": "Habilitado", + "API Keys": "Chaves da API", + "Group Key": "Chave do Grupo", + "Allowed IPs": "IPs Permitidos", + "Separate with commas, no spaces": "Separar com vírgulas, sem espaços", + "Can Get Monitors": "Pode Obter Monitores", + "Can Get Logs": "Pode Obter Logs", + "Can Control Monitors": "Pode Controlar Monitores", + "Can View Snapshots": "Pode Visualizar Snapshots", + "Can View Streams": "Pode Visualizar Transmissões", + "Can View Videos": "Pode Visualizar Vídeos", + "Can View Monitor": "Pode Visualizar Monitores", + "Can Edit Monitor": "Pode Editar Monitores", + "Can Delete Videos": "Pode Deletar Vídeos", + "Delete Video": "Deletar Vídeo", + "Can View Videos and Events": "Pode Visualizar Vídeos e Eventos", + "Can Delete Videos and Events": "Pode Deletar Vídeos e Eventos", + "Saved Filters": "Filtros Salvos", + "Filter Name": "Filtrar Nome", + "Find Where": "Encontrar Onde", + "Sort By": "Ordenar Por", + "Start Time": "Hora de Início", + "End Time": "Hora de Término", + "Monitor ID": "ID do Monitor", + "File Type": "Tipo de Arquivo", + "Filesize": "Tamanho do Arquivo", + "Video Status": "Status do Vídeo", + "Preferences": "Preferências", + "Equal to": "Igual a", + "Not Equal to": "Não Igual a", + "Greater Than or Equal to": "Maior ou Igual a", + "Greater Than": "Maior que", + "Less Than": "Menor que", + "Less Than or Equal to": "Menor ou Igual a", + "Like": "Como", + "Matches": "Combina", + "Not Matches": "Não Combina", + "In": "Em", + "Not In": "Não Em", + "ASC": "ASC", + "DESC": "DESC", + "Action for Selected": "Ação para Selecionado", + "Search": "Procurar", + "No": "Não", + "Yes": "Sim", + "Start": "Iniciar", + "End": "Finalizar", + "Archive": "Arquivar", + "Email Details": "Detalhes do E-mail", + "Delete Matches": "Deletar Combinações", + "Delete selected": "Deletar Selecionado", + "Execute Command": "Executar Comando", + "for Global Access": "para Acesso Global", + "Help": "Ajuda", + "Don't show this anymore": "Não mostre isso mais", + "Chat on Discord": "Conversar no Discord", + "Documentation": "Documentação", + "All Monitors": "Todos Monitores", + "Motion Meter": "Medidos de Movimento", + "FFmpegTip": "FFprobe is a simple multimedia streams analyzer. You can use it to output all kinds of information about an input including duration, frame rate, frame size, etc.", + "Complete Stream URL": "URL de transmissão completa", + "ONVIF Scanner": "ONVIF Scanner", + "Scan Settings": "Configurações de digitalização", + "ONVIFnote": "Descubra os dispositivos ONVIF em redes fora da sua ou deixe em branco para escanear sua rede atual.
O nome de usuário e a senha podem ser deixados em branco.", + "Range or Single": "Range or Single", + "IP Address": "Endereço IP", + "Port": "Porta", + "Camera Username": "Usuário da câmera", + "Camera Password": "Senha da câmera", + "Found Devices": "Dispositivos encontrados", + "Switch on for Still Image": "Ligar para manter imagem", + "Live Stream Toggle": "Mostrar transmissão ao vivo", + "RegionNote": "Os pontos só são salvos quando você pressiona Salvar na janela de Configurações do Monitor.", + "Points": "Pontos Ao adicionar pontos, clique na borda do polígono.", + "Indifference": "Indiferença", + "Region Name": "Nome da região", + "Regions": "Regiões", + "Again": "De novo", + "Account Info": "Informações da conta", + "blankPassword": "Deixe em branco para manter a mesma senha", + "2-Factor Authentication": "Autenticação de 2 fatores", + "Max Storage Amount": "Montante máximo de armazenamento em Megabytes", + "Number of Days to keep": "Número de dias para manter", + "Monitor Groups": "Grupos de monitores", + "Group Name": "Nome do grupo", + "WebDAV": "WebDAV", + "URL": "URL", + "Autosave": "Auto salvar", + "Save Directory": "Salvar diretório", + "CSS": "CSS Personalize seu painel de controle.", + "Monitors per row": "Monitores por linha para montagem", + "Browser Console Log": "Navegador de logs", + "All Monitors and Privileges": "Todos monitores e privilégios", + "Permissions": "Permissões", + "Time-lapse Tool": "Ferramenta Time-laps", + "total": "total", + "MB": "MB", + "Calendar": "Calendário", + "Leave blank for random.": "Deixe em branco para aleatório.", + "Currently viewing": "Visualizando atualmente", + "Status Indicator": "Indicador de status", + "Show Logs": "Mostrar logs", + "Videos List": "Lista de vídeos", + "Monitor Settings": "Configurações do monitor", + "Enlarge": "Prolongar", + "Fullscreen": "Tela cheia", + "Value": "Valor", + "Idle": "Inativo", + "Disabled": "Desabilitado", + "Record": "Gravar", + "Watch Only": "Visualizar apenas", + "Toggle Sidebar": "Mostrar barra lateral", + "Add Monitor": "Adicionar monitor", + "Start Recording": "Iniciar gravação", + "Set to Watch Only": "Definir para apenas visualizar", + "Save as": "Salvar como", + "Add New": "Adicionar novo", + "Delete Selected Videos": "Excluir vídeos selecionados", + "DeleteSelectedVideosMsg": "Deseja excluir esses vídeos? Você não poderá recuperá-los.", + "clientStreamFailedattemptingReconnect": "A verificação ctream do lado do cliente falhou, tentando reconectar.", + "Delete Filter": "Excluir filtro", + "confirmDeleteFilter": "Deseja excluir este filtro? Você não poderá recuperá-lo.", + "Fix Video": "Corrigir Vídeo", + "FixVideoMsg": "Você deseja corrigir esse vídeo? Você não poderá desfazer essa ação..", + "DeleteVideoMsg": "Deseja excluir este vídeo? Você não poderá recuperá-lo.", + "dropBoxSuccess": "Sucesso! Arquivos salvos em seu Dropbox.", + "API Key Deleted": "Chave da API excluída", + "APIKeyDeletedText": "A chave foi excluída. Não funcionará mais.", + "API Key Added": "Chave da API adicionada", + "APIKeyAddedText": "Você pode usar essa chave agora", + "Filters Updated": "Filtros atualizados", + "FiltersUpdatedText": "Suas alterações foram salvas e aplicadas.", + "Settings Changed": "Configurações Alteradas", + "SettingsChangedText": "Suas configurações foram salvas e aplicadas.", + "Import Monitor Configuration": "Importar Configuração do Monitor", + "ImportMonitorConfigurationText": "Fazer isso substituirá todas as alterações atualmente não salvas. As mudanças importadas só serão aplicadas quando você pressionar Salvar.", + "Paste JSON here.": "Cole o JSON aqui.", + "Delete Monitor": "Deletar Monitor", + "DeleteMonitorText": "Deseja excluir este monitor? Você não pode recuperá-lo. Os arquivos para essa ID permanecerão no sistema de arquivos. Se você optar por recriar um monitor com a mesma identificação, os vídeos e eventos tornar-se-ão visíveis no painel de controle.", + "Invalid JSON": "JSON inválido", + "InvalidJSONText": "Certifique-se de que esta seja uma string JSON válida para a configuração do monitor Shinobi.", + "Passwords don't match": "As senhas não combinam", + "No Events found for this video": "Nenhum evento encontrado para este vídeo", + "Video and Time Span (Minutes)": "Vídeo e intervalo de tempo (minutos)", + "Video Length (minutes) and Motion Count per video": "Comprimento do vídeo (minutos) e Contagem de movimento por vídeo", + "Counts of Motion": "Contagem de movimento", + "Unable to Launch": "Incapaz de executar", + "UnabletoLaunchText": "Salve primeiro o monitor novo. Em seguida, tente iniciar o editor da região.", + "NoVideosFoundForDateRange": "Nenhum vídeo encontrado neste intervalo de datas. Tente definir a data de início mais adiante.", + "monitorEditFailedMaxReached": "Sua conta atingiu o número máximo de câmeras que podem ser criadas. Fale com um administrador se você gostaria que isso mudasse.", + "in": "em", + "ago": "atrás", + "a few seconds": "alguns segundos", + "a minute": "um minuto", + "minutes": "minutos", + "an hour": "uma hora", + "hours": "horas", + "a day": "um dia", + "days": "dias", + "a month": "um mês", + "months": "meses", + "a year": "um ano", + "years": "anos", + "Identity": "Identidade", + "Input": "Entrada", + "Stream": "Transmissão", + "Stream Timestamp": "Transmitindo horário", + "Stream Watermark": "Transmitindo marca d'água", + "JPEG API": "JPEG API Snapshot (cgi-bin)", + "Recording": "Gravando", + "Recording Timestamp": "Gravando horário", + "Recording Watermark": "Gravando marca d'água", + "Region Editor": "Editor de região", + "Custom": "Customizado", + "Detector": "Detector", + "Connected": "Conectado", + "Not Connected": "Não conectado", + "Lisence Plate Detector": "Detector de placas", + "OpenCV Cascades": "OpenCV Cascatas", + "Refresh List of Cascades": "Atualizar Lista de Cascatas", + "\"No Motion\" Detector": "\"Sem movimento\" Detector", + "Control": "Controle", + "Grouping": "Agrupando   Adicione grupos em Configurações", + "Logging": "Logging", + "IdentityText1": "É assim que o sistema irá identificar os dados para este fluxo. Você não pode alterar o ID do Monitor uma vez que você pressionou salvar. Se você quiser, você pode fazer o ID do Monitor mais legível para humanos antes de continuar.", + "IdentityText2": "Você pode duplicar um monitor modificando o ID do Monitor e depois pressionando salvar. Você não pode usar o ID de um monitor que já existe ou ele economizará sobre as informações do banco de dados desse monitor.", + "noSpecialCharacters": "Sem espaços ou caracteres especiais.", + "NotesPlacholder": "Comentários que você quer deixar para as configurações desta câmera.", + "InputText1": "Esta seção diz a Shinobi como consumir um fluxo. Para um desempenho ideal, tente ajustar as configurações internas da sua câmera. Encontre as seguintes opções e defina-as como mostrado. Para encontrar sua câmera, você pode usar o ONVIF Scanner embarcado do Shinobi. Algumas câmeras ONVIF requerem o uso de uma ferramenta de gerenciamento para modificar suas configurações internas. Se você não consegue encontrar suas câmeras, você pode tentar Gerenciador de dispositivos ONVIF para Windows.", + "InputText2": "
  • Taxa de quadros por segundo (FPS) : High : 10 - 15 FPS, Low : 2-5 FPS
  • I-frame interval : 80
  • Bit Rate Type : CBR (Constant Bit Rate)
  • Bit Rate : entre 256kbps - 500kbps
", + "InputText3": "Se você precisar de ajuda para descobrir o tipo de entrada que sua câmera é, você pode dar uma olhada no Camera URLs List na página do Shinobi.", + "StreamText": "

Esta seção designará o método do fluxo primário e as configurações. Este fluxo será exibido no painel. Se você optar por usar HLS, JPEG ou MJPEG, então você pode consumir o fluxo através de outros programas.

Usar o fluxo de JPEG essencialmente desativa o fluxo primário e usa o compartimento de instantâneos para obter quadros.

", + "DetectorText": "

Quando as caixas de Largura e Altura são mostradas, você deve configurá-las para 640x480 ou abaixo. Isso otimizará a velocidade de leitura dos quadros.

", + "RecordingText": "Recomenda-se que você defina Tipo de arquivo de gravação para WebMMP4 e Video Codec para libvpxcopie ou libx264 porque seu Tipo de Entrada está definido para .", + "Name": "Nome", + "Retry Connection": "Tentar novamente a conexão Número de vezes permitido falhar", + "Notes": "Notas", + "Input Type": "Tipo de entrada", + "Connection Type": "Tipo de conexão", + "RTSP Transport": "Transporte RTSP", + "Host": "Host", + "Force Port": "Forçar porta", + "Path": "Caminho", + "Monitor Capture Rate": "Taxa de captura do monitor (FPS)", + "Analyzation Duration": "Duração da análise", + "Probe Size": "Probe Size", + "Stream Type": "Tipo de transmissão", + "# of Allow MJPEG Clients": "# para permitir clientes MJPEG 0 para infinito", + "HLS Video Encoder": "Codificador de vídeo HLS", + "HLS Audio Encoder": "Codificador de áudio HLS", + "HLS Segment Length": "Comprimento do segmento HLS em segundos", + "HLS Preset": "Pré-definição HLS", + "HLS List Size": "Tamanho da lista HLS", + "Check Signal Interval": "Verifique o intervalo do sinal em minutos", + "Log Signal Event": "Evento de sinal de registro Apenas cliente", + "Quality": "Qualidade 1 para alta, 23 para Low", + "Rate": "Taxa (FPS)", + "Width": "Largura", + "Height": "Altura", + "Rotate": "Rotação", + "Video Filter": "Filtro de vídeo", + "Font Path": "Caminho da fonte", + "Font Size": "Tamanho da fonte", + "Text Color": "Cor do texto", + "Text Box Color": "Cor da caixa de texto", + "Position X": "Posição X", + "Position Y": "Posição Y", + "Image Location": "Localização da imagem Caminho Absoluto ou deixar em branco para usar global", + "Image Position": "Posição da imagem", + "Frame Rate": "Taxa de quadros (FPS)", + "Image Width": "Largura da imagem", + "Image Height": "Altura da imagem", + "Record File Type": "Tipo de arquivo de gravação", + "Video Codec": "Video Codec", + "Preset": "Pré-definição", + "Audio Codec": "Audio Codec", + "Video Record Rate": "Taxa de gravação de vídeo (FPS)", + "Record Width": "Largura da gravação", + "Record Height": "Altura da gravação", + "Double Quote Directory": "Diretório com aspas duplas Alguns diretórios têm espaços. Usar isso pode bloquear algumas câmeras.", + "Recording Segment Interval": "Intervalo de Segmento de Gravação em minutos", + "Record Video Filter": "Gravar filtro de vídeo", + "Input Flags": "Flags de entrada", + "Snapshot Flags": "Snapshot Flags", + "Detector Flags": "Detector de Flags", + "Stream Flags": "Flags de Transmissão", + "Stream to YouTube": "Transmitir para o YouTube", + "Stream to YouTube Flags": "Transmitir para o YouTube Flags", + "Recording Flags": "Gravando Flags", + "Output Method": "Método de saída", + "Webhook": "Webhook", + "Webhook URL": "Webhook URL", + "Command on Trigger": "Comando quando acionado", + "Command": "Comando", + "Allow Next Command": "Habilitar próximo comando em minutos", + "Allow Next Trigger": "Habilitar próxima ação em milissegundos", + "Save Events to SQL": "Salvar eventos no SQL", + "Email on Trigger": "E-mail quando acionado Emails vão para o endereço de login do titular da conta principal.", + "Allow Next Email": "Permitir próximo e-mail em minutos", + "How to Record": "Como gravar", + "Trigger Record": "Acionar registro", + "Recording Timeout": "Gravando Timeout em minutos", + "Timeout Reset on Next Motion": "Timeout reiniciará no próximo movimento", + "Delete Motionless Video": "Deletar vídeos sem movimento", + "Send Frames": "Enviar quadros Envie os quadros a serem analisados", + "Detector Rate": "Taxa do detector (FPS)", + "Feed-in Image Width": "Largura da imagem de entrada", + "Feed-in Image Height": "Altura da imagem de entrada", + "Check for Motion First": "Verifique primeiro o movimento", + "Detect Objects": "Detectar objetos Veja abaixo", + "Full Frame Detection": "Detecção de quadro completo", + "Country of Plates": "País das placas", + "Email on No Motion": "E-mail em \"Sem movimento\"", + "Timeout": "Timeout", + "Controllable": "Controlável", + "Custom Base URL": "URL Customizada Deixe em branco para usar URL do Host", + "Stop URL": "Parar URL", + "URL Stop Timeout": "URL timeout máximo Parar URL depois de X milissegundos", + "Center": "Centro URL Address", + "Left": "Esquerda URL Address", + "Left Stop": "Esquerda máxima URL Address", + "Right": "Direita URL Address", + "Right Stop": "Direita máxima URL Address", + "Up": "Cima URL Address", + "Up Stop": "Cima máximo URL Address", + "Down": "Baixo URL Address", + "Down Stop": "Baixo máximo URL Address", + "Enable Night Vision": "Ativar visão noturna URL Address", + "Disable Night Vision": "Desativar visão noturna URL Address", + "Zoom Out Stop": "Parar menos zoom URL Address", + "Zoom In Stop": "Parar mais zoom URL Address", + "Log Level": "Nível de registro", + "Save Log in SQL": "Salvar log em SQL Isso pode encher rapidamente.", + "JPEG": "JPEG", + "MJPEG": "MJPEG", + "H.264 / H.265 / H.265+": "H.264 / H.265 / H.265+", + "HLS (.m3u8)": "HLS (.m3u8)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4 (.mp4 / .ts)", + "Shinobi Streamer": "Shinobi Streamer", + "Dashcam (Streamer v2)": "Dashcam (Streamer v2)", + "Local": "Local", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "RTSP": "RTSP", + "UDP": "UDP", + "Auto": "Auto", + "TCP": "TCP", + "Base64 over Websocket": "Base64 sobre Websocket", + "JPEG (Auto Enables JPEG API)": "JPEG (Auto habilitado JPEG API)", + "HLS (includes Audio)": "HLS (inclui áudio)", + "libx264": "libx264", + "libx265": "libx265", + "copy": "copiar", + "No Audio": "Sem áudio", + "aac": "aac", + "ac3": "ac3", + "libmp3lame": "libmp3lame", + "No Rotation": "Sem rotação", + "180 Degrees": "180 Graus", + "90 Counter Clockwise and Vertical Flip (default)": "90 no sentido anti-horário e vertical (Padrão)", + "90 Clockwise": "90 no sentido horário", + "90 Clockwise and Vertical Flip": "90 no sentido horário e vertical", + "Top Right": "Superior direito", + "Top Left": "Superior esquerdo", + "Bottom Right": "Inferior direito", + "Bottom Left": "Inferior esquerdo", + "WebM (libvpx)": "WebM (libvpx)", + "MP4 (copy, libx264, libx265)": "MP4 (copy, libx264, libx265)", + "Default": "Padrão", + "libvpx (Default)": "libvpx (Padrão)", + "libvpx-vp9": "libvpx-vp9", + "libx264 (Default)": "libx264 (Padrão)", + "libvorbis (Default)": "libvorbis (Padrão)", + "libopus": "libopus", + "aac (Default)": "aac (Padrão)", + "Hotswap Modes (Watch-Only)": "Hotswap Modes (Visualizar Apenas)", + "Delete Motionless Videos (Record)": "Eliminar vídeos sem movimento (Gravação)", + "US": "US", + "EU": "EU", + "Silent": "Silencioso", + "Fatal": "Fatal", + "on Error": "em Erro", + "All Warnings": "Todos avisos", + "Debug": "Debugar", + "Export": "Exportar", + "Import": "Importar", + "Simple": "Simples", + "Advanced": "Avançado", + "Error Connecting": "Erro ao conectar", + "DB Lost.. Retrying..": "Banco de dados perdido... Repetindo...", + "Retrying...": "Repetindo...", + "Filter Matches": "Combinações de filtro", + "FilterMatchesText1": "Este filtro atingiu as condições.", + "FilterMatchesText2": "vídeos encontrados.", + "Executed": "Executado", + "Deleted": "Deletado", + "Query": "Pesquisa", + "Filter ID": "Filtrar ID", + "Webdav Error": "Erro Webdav", + "WebdavErrorText": "Não é possível salvar. Você criou os diretórios da câmera dentro do seu diretório de escolhido para isso?", + "File Not Exist": "Arquivo inexistente", + "FileNotExistText": "Não é possível salvar o arquivo inexistente. Algo deu errado.", + "CameraNotRecordingText": "As configurações podem ser incompatíveis. Verifique os encoders. Reiniciando...", + "Camera is not recording": "Câmera não está gravando", + "Camera is not streaming": "Câmera não está transmitindo", + "Restarting Process": "Reiniciado processo", + "Monitor Stopped": "Monitor parado", + "MonitorStoppedText": "A sessão do monitor foi ordenada a parar.", + "Monitor Idling": "Monitor ocioso", + "MonitorIdlingText": "A sessão do monitor foi ordenada para ocioso.", + "NoMotionEmailText1": "Nenhum movimento para", + "NoMotionEmailText2": "Não houve nenhum movimento detectado na câmera para", + "Monitor Name": "Nome do monitor", + "Process Unexpected Exit": "Saída inesperado do processo", + "Process Crashed for Monitor": "Processo de Monitor quebrado", + "FFmpegCantStart": "FFmpeg não pôde iniciar", + "FFmpegCantStartText": "O mecanismo de gravação para esta câmera não pôde começar. Pode haver algo errado com a configuração da sua câmera. Se houver algum registro diferente deste, por favor, coloque-os em Problemas no Github.", + "JPEG Error": "Erro JPEG", + "JPEGErrorText": "Houve um problema ao obter dados da sua câmera.", + "Fatal Maximum Reached": "Máximo atingido, parando câmera.", + "FatalMaximumReachedText": "Erro JPEG fatal.", + "Incorrect Settings Chosen": "Configuração incorreta escolhida", + "Can't Connect": "Não pode conectar", + "Video Finished": "Vídeo finalizado", + "No Monitor Found, Ignoring Request": "Monitor não encontrado, ignorando requisição", + "Event": "Evento", + "EventText1": "Disparou um evento de movimento", + "EventText2": "Não foi possível enviar imagem de e-mail, o arquivo não foi acessado", + "MailError": "MAIL ERROR : Não foi possível enviar e-mail, verifique conf.json. Ignorando qualquer recurso que dependa do envio", + "updateKeyText1": "\"updateKey\" faltando em \"conf.json\", não é possível atualizar dessa maneira até você adicionar", + "updateKeyText2": "\"updateKey\" incorreta", + "Control Error": "Erro de controle", + "ControlErrorText1": "Controle não está ativado", + "NotAuthorizedText1": "Não autorizado, envie o comando inicial com \"auth\",\"ke\", e \"uid\"", + "Fields cannot be empty": "Campos não podem estar vazios", + "AccountEditText1": "Não foi possível editar. Atualize a página se o problema continuar", + "Not an Administrator Account": "Não é uma conta de Administrador", + "superAdminText": "\"super.json\" não existe. Por favor, renomeie \"super.sample.json\" para \"super.json\".", + "Enter this code to proceed": "Informe este código para prosseguir", + "FactorAuthText1": "O código vai estar ativo somente por 15 minutos. Se você entrar novamente o temporizador será reiniciado para 15 minutos com o mesmo código", + "monitorEditText1": "Dados inválidos. Verifique se esta é uma string de importação válida.", + "monitorEditText2": "String de detalhes inválida. Certifique-se de ser uma string JSON e não um objeto comum que está sendo informado", + "Monitor Updated by user": "Monitor atualizado pelo usuário", + "Monitor Added by user": "Monitor adicionado pelo usuário", + "monitorGetText1": "Requisição incompleta. Remova a última barra da URL ou informe um valor válido", + "Monitor mode changed": "Modo de monitor mudou", + "Reset Timer": "Temporizador de reinicialização", + "Monitor mode is already": "Modo de monitor já está em uso", + "Monitor or Key does not exist.": "Monitor ou chave não existe", + "No Group with this key exists": "Nenhum grupo com esta chave foi encontrado", + "Trigger Successful": "Disparou bem sucedido", + "No such file": "Arquivo inexistente", + "modifyVideoText1": "Método não existe. Verifique se o último valor da URL não está em branco", + "CPU indicator will not work. Continuing...": "Indicador de CPU não irá funcionar. Continuando...", + "startUpText0": "Verificação de tamanho para vídeos", + "startUpText1": "Verificação de fim de tamanho para vídeos", + "startUpText2": "Todos usuário verificados. Aguarde para fechar arquivos abertos e remover arquivos por limite de usuário", + "startUpText3": " Esperando dar uma verificação de vídeo inacabada algum tempo. 3 segundos", + "startUpText4": "Iniciando todos os monitores para assistir e gravar", + "startUpText5": "Shinobi está pronto.", + "Edit": "Editar", + "Dashboard Language": "Idioma do Painel de Controle", + "File Not Found": "Arquivo não encontrado", + "No Monitor Exists with this ID.": "Não existem monitores com esse ID.", + "Cannot watch a monitor that isn't running.": "Não pode assistir um monitor que não está rodando.", + "Not Permitted": "Não permitidos", + "Not Authorized": "Não autorizados", + "Generate Subtitles": "Gerar legendas", + "Video Limit":"Limite de vídeo", + "Preview":"Visualização", + "Websocket Connected":"Websocket conectado", + "Websocket Disconnected":"Websocket desconectado", + "New Authentication Token":"Novo token de autenticação", + "All Logs":"Todos logs", + "For Group":"Para grupo", + "Basic Authentication":"Autenticação básica", + "Superuser Logs":"Logs do Superusuário", + "Authentication Failed":"Autenticação falhou", + "Max Number of Cameras":"Número máximo de câmeras", + "Can edit Max Storage":"Pode editar Armazenamento Máximo", + "Can edit Max Days":"Pode editar Máximo de Dias", + "in Days":"em Dias", + "Can edit how long to keep Logs":"Pode editar por quanto tempo maneter logs", + "Can use Admin Panel":"Pode usar Painel Administrativo", + "Can use WebDAV":"Pode usar WebDAV", + "Can use LDAP":"Pode usar LDAP", + "Can edit how long to keep Events":"Pode editar quanto tempo manter eventos", + "Leave blank for unlimited":"Deixe em branco para ilimitado", + "Limited":"Limitado", + "All Privileges":"Todos Privilégios", + "LDAP":"LDAP", + "LDAP Success":"LDAP Sucesso", + "LDAP User Authenticated":"Usuário LDAP Usuário Autenticado", + "LDAP User is New":"Usuário LDAP é Novo", + "Creating New Account":"Criando Nova Conta", + "bindDN":"Vincular DN", + "Bind Credentials":"Vincular Credenciais (Senha)", + "Search Base":"Base de Pesquisa", + "Mode": "Modo", + "Search Filter":"Procurar Filtro" +} diff --git a/languages/ru.json b/languages/ru.json new file mode 100644 index 0000000..79063d4 --- /dev/null +++ b/languages/ru.json @@ -0,0 +1,496 @@ +{ + "\"No Motion\" Detector": "\"Нет Движения\" Детектор", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "180 Degrees": "180 градусов", + "2-Factor Authentication": "2-Факторной Аутентификации", + "90 Clockwise": "90 по часовой стрелке", + "90 Clockwise and Vertical Flip": "90 по часовой стрелке и вертикальный флип", + "90 Counter Clockwise and Vertical Flip (default)": "90 против часовой стрелки и по вертикали (по умолчанию)", + "API": "API-интерфейс", + "API Key Added": "Ключ API добавлены", + "API Key Deleted": "API-ключ удален", + "API Keys": "Ключи API", + "APIKeyAddedText": "Вы можете использовать этот ключ сейчас.", + "APIKeyDeletedText": "Ключ был удален. Он больше не будет работать.", + "ASC": "АСК", + "Account Info": "Счета Информация", + "AccountEditText1": "Не мог изменить. Обновить страницу, если проблема продолжается.", + "Accounts": "Счетов", + "Action for Selected": "Действие для выбранных", + "Add": "Добавить", + "Add Monitor": "Добавить Монитор", + "Add New": "Добавить Новый", + "Admin": "Админ", + "Advanced": "Расширенный", + "Again": "Снова", + "All Monitors": "Все Мониторы", + "All Monitors and Privileges": "Все мониторы и привилегии", + "All Warnings": "Все Предупреждения", + "Allow Next Command": "Разрешить следующей команды в течение нескольких минут", + "Allow Next Email": "Разрешить следующей электронной почте в течение нескольких минут", + "Allow Next Trigger": "Допустить следующего триггера в Миллисекундах", + "Allowed IPs": "Допускается ИПС", + "Analyzation Duration": "Продолжительность Анализа", + "Archive": "Архив", + "Audio Codec": "Аудио Кодек", + "Authenticate": "Аутентифицировать", + "Auto": "Авто", + "Autosave": "Автосохранение", + "Base64 over Websocket": "В base64 через websocket", + "Bottom Left": "Внизу Слева", + "Bottom Right": "Нижний Правый", + "Browser Console Log": "Консоли Браузера Войти", + "CPU": "Процессор", + "CPU indicator will not work. Continuing...": "Индикатор процессора не будет работать. Продолжение...", + "CSS": "В CSS Стиль вашей приборной панели.", + "Calendar": "Календарь", + "Camera Password": "Пароль Камеры", + "Camera Username": "Имя Пользователя Камеры", + "Camera is not recording": "Камера не записывает", + "CameraNotRecordingText": "Параметры могут быть несовместимы. Проверить датчики. Перезапуск...", + "Can Control Monitors": "Может Управлять Мониторами", + "Can Delete Videos": "Можно Удалять Видео", + "Can Delete Videos and Events": "Можно удалять видео и событий", + "Can Edit Monitor": "Можете Редактировать Монитор", + "Can Get Logs": "Можете Сделать Логи", + "Can Get Monitors": "Можете Сделать Мониторы", + "Can View Monitor": "Можно Посмотреть Монитор", + "Can View Snapshots": "Можете Посмотреть Снимки", + "Can View Streams": "Можете Посмотреть Потоков", + "Can View Videos": "Можете Посмотреть Видео", + "Can View Videos and Events": "Можете посмотреть видео и событий", + "Can't Connect": "Не могу подключиться", + "Center": "Центр URL-Адрес", + "Chat on Discord": "Чат на раздор", + "Check": "Проверить", + "Check Signal Interval": "Проверка сигнала интервал в минутах", + "Check for Motion First": "Проверить в первую очередь для движения", + "Close": "Закрыть", + "Closed": "Закрытые", + "Command": "Команда", + "Command on Trigger": "Команду на триггер", + "Complete Stream URL": "Полный URL-адрес потока", + "Confirm": "Подтвердить", + "Connected": "Подключен", + "Connection Type": "Тип Подключения", + "Control": "Контроль", + "Control Error": "Ошибка Контроля", + "ControlErrorText1": "Контроль не включен", + "Controllable": "Управляема", + "Country of Plates": "Страна пластин", + "Counts of Motion": "Подсчитывает движения", + "Current": "Тока", + "Currently viewing": "В настоящее время просмотр", + "Custom": "Заказ", + "Custom Base URL": "Базовый пользовательский URL-адрес оставить пустым, чтобы использовать URL-адрес узла", + "DB Lost.. Retrying..": "База Данных Потеряла.. Повтор..", + "DESC": "Описание", + "Dashboard": "Приборной панели", + "Dashboard Language": "Язык Приборной Панели", + "Dashcam": "Автомобильный видеорегистратор", + "Dashcam (Streamer v2)": "Автомобильный видеорегистратор (Стример П2)", + "Date Range": "Диапазон Дат", + "Debug": "Отлаживать", + "Default": "По умолчанию", + "Delete": "Удалить", + "Delete Filter": "Удалить Фильтр", + "Delete Matches": "Удалить Играм", + "Delete Monitor": "Удалить Монитор", + "Delete Motionless Video": "Удалить Недвижно Видео", + "Delete Motionless Videos (Record)": "Удалить Неподвижными Видео (Запись)", + "Delete Selected Videos": "Удаление Выбранного Видео", + "Delete Video": "Удалить Видео", + "Delete selected": "Удалить выбранные", + "DeleteMonitorText": "Вы действительно хотите удалить этот монитор? Нельзя восстановить. Файлы для этот идентификатор будет оставаться в файловой системе. Если вы решили воссоздать монитора с одинаковым кодом видео и события станут видны в личном кабинете.", + "DeleteSelectedVideosMsg": "Вы действительно хотите удалить эти видео? Вы не сможете восстановить их.", + "DeleteVideoMsg": "Вы действительно хотите удалить это видео? Нельзя восстановить.", + "Deleted": "Удален", + "Detect Objects": "Обнаруживать объекты ниже", + "Detector": "Детектор", + "Detector Flags": "Флаги Детектор", + "Detector Rate": "Детектор скорости (ФПС)", + "DetectorText": "

Когда показана Ширина и Высота коробки, вы должны установить их до 640х480 или ниже. Это позволит оптимизировать скорость чтения кадров.

", + "Disable Night Vision": "Отключить ночное видение URL-Адрес", + "Disable Nightvision": "Отключение Ночного Видения", + "Disabled": "Отключен", + "Documentation": "Документация", + "Don't show this anymore": "Больше не показывать это", + "Double Quote Directory": "Двойная Кавычка каталога у некоторых каталогов есть пробелы. С помощью этого может произойти сбой некоторых камер.", + "Down": "Вниз URL-Адрес", + "Down Stop": "Вниз стоп URL-Адрес", + "Download": "Скачать", + "EU": "ЕС", + "Edit": "Редактировать", + "Email": "Электронной почты", + "Email Details": "Подробности По Электронной Почте", + "Email on No Motion": "Электронной почты на \"нет движения\"", + "Email on Trigger": "Электронной почты на Триггерных писем перейти к главной владельца счета адрес для входа.", + "Enable Night Vision": "Включение ночного видения URL-Адрес", + "Enable Nightvision": "Включение Ночного Видения", + "Enabled": "Включен", + "End": "Конец", + "End Time": "Время Окончания", + "Ended": "Закончился", + "Enlarge": "Увеличить", + "Enter this code to proceed": "Введите этот код, чтобы продолжить", + "Equal to": "Равна", + "Error Connecting": "Ошибка Подключения", + "Event": "Событие", + "Event Limit": "Лимит Событие", + "EventText1": "Срабатывает событие движения в", + "EventText2": "Не мог изображения по электронной почте, файл не был доступен", + "Events": "События", + "Example": "Пример", + "Execute Command": "Выполнить Команду", + "Executed": "Выполнен", + "Export": "Экспорт", + "FFmpegCantStart": "Видео не смог запустить", + "FFmpegCantStartText": "Запись двигатель для этой камеры не удалось запустить. Там может быть что-то не так с настройкой камеры. Если есть какие-либо другие журналы, чем этот, пожалуйста, пишите в вопросы на github.", + "FFmpegTip": "FFprobe-простой мультимедийный анализатор потоков. Вы можете использовать его для вывода всевозможной информации о входных данных, включая Продолжительность, частоту кадров, Размер кадра и т. д.", + "FFprobe": "Зонд", + "FactorAuthText1": "Код будет активна только в течение 15 минут. Если вы войти снова, Таймер будет сброшен до 15 минут с тем же кодом.", + "Fatal": "Роковой", + "Fatal Maximum Reached": "Роковой Максимальным Достигнутым, Останавливая Камеру.", + "FatalMaximumReachedText": "Ошибка JPEG был смертельным.", + "Feed-in Image Height": "Кормить-в Высота изображения", + "Feed-in Image Width": "Кормить-в изображения Ширина", + "Fields cannot be empty": "Поля не могут быть пустыми", + "File Not Exist": "Файл Не Существует", + "File Not Found": "Файл Не Найден", + "File Type": "Тип Файла", + "FileNotExistText": "Не удается сохранить файл не существует. Что-то пошло не так.", + "Filename": "Именем", + "Filesize": "Размер", + "Filter ID": "Идентификатор фильтра", + "Filter Matches": "Фильтра", + "Filter Name": "Название Фильтра", + "FilterMatchesText1": "Этот фильтр имеет условия.", + "FilterMatchesText2": "видео нашли.", + "Filters": "Фильтры", + "Filters Updated": "Фильтры Обновлены", + "FiltersUpdatedText": "Ваши изменения были сохранены и применены.", + "Find Where": "Найти Где", + "Fix": "Исправить", + "Fix Video": "Исправить Видео", + "FixVideoMsg": "Вы хотите, чтобы удалить это видео? Вы не можете отменить это действие.", + "Font Path": "Путь Шрифта", + "Font Size": "Размер Шрифта", + "Force Port": "Сила Порта", + "Found Devices": "Найденные Устройства", + "Frame Rate": "Частота кадров (кадров / с)", + "Full Frame Detection": "Полное Обнаружение Кадра", + "Fullscreen": "Полноэкранный", + "Greater Than": "Больше", + "Greater Than or Equal to": "Больше или равна", + "Group Key": "Ключевые Группы", + "Group Name": "Название Группы", + "Grouping": "Группировка ", + "H.264 / H.265 / H.265+": "Формат H. 264 / H. 265 / H. 265 В ", + "HLS (.m3u8)": "ЗОЖ (.m3u8 форматов)", + "HLS (includes Audio)": "ЗОЖ (включает Аудио)", + "HLS Audio Encoder": "ЗОЖ Аудио Шифратор", + "HLS List Size": "Размер списка ЗОЖ", + "HLS Preset": "ЗОЖ предустановленных", + "HLS Segment Length": "ЗОЖ сегмент длиной в секунд", + "HLS Video Encoder": "ЗОЖ видео Энкодера", + "HTTP": "Протокол http", + "HTTPS": "Протоколу https", + "Height": "Высота", + "Help": "Помогите", + "Hide List": "Скрыть Список", + "Hide Notes": "Скрыть Примечания", + "Host": "Хозяин", + "Hotswap Modes (Watch-Only)": "Режима Горячей Замены (Часы Только)", + "How to Record": "Как записать", + "IP Address": "IP-адрес", + "Identity": "Личность", + "IdentityText1": "Это как система будет определять данные для этого потока. Вы не можете изменить идентификатор монитора после того, как вы нажали \"сохранить\". Если вы хотите, вы можете сделать монитор код более читабельным, прежде чем продолжить.", + "IdentityText2": "Вы можете дублировать монитор, изменяя идентификатор монитора нажмите клавишу сохранить. Вы не можете использовать идентификатор монитора, который уже существует или он сохранит за монитора базы данных.", + "Idle": "Праздный", + "Image Height": "Высота Изображения", + "Image Location": "Изображения Расположение абсолютный путь или оставьте поле пустым, чтобы использовать глобальные", + "Image Position": "Положение Изображения", + "Image Width": "Ширина Изображения", + "Import": "Импорт", + "Import Monitor Configuration": "Импорт Конфигурации Монитора", + "ImportMonitorConfigurationText": "Это overrwrite любые изменения в настоящее время не сохранены. Импортированные изменения будут применены только при нажатии сохранить.", + "In": "В", + "Incorrect Settings Chosen": "Выбраны Неправильные Параметры", + "Indifference": "Равнодушие", + "Input": "Вход", + "Input Flags": "Входных Флагов", + "Input Type": "Тип Входного Сигнала", + "InputText1": "Этот раздел рассказывает шиноби, как использовать поток. Для оптимальной производительности, попробуйте настройки внутренних параметров камеры. Найти следующие варианты и установить их, как показано. Чтобы найти вашу камеру, вы можете использовать встроенный onvif и сканер шиноби. Некоторые камеры onvif требуют использования инструмента управления, чтобы изменить свои внутренние настройки. Если Вы не можете найти вашей камеры вы можете попробовать onvif и диспетчер устройств для Windows.", + "InputText2": "
  • Кадров (fps) : высокая : 10 - 15 ФПС, минимум : 2-5 ФПС
  • I-кадр интервал : 80
  • Тип битрейта : CBR (Постоянный Битрейт)
  • Битрейт : между 256кбит / с - 500 Кбит / с
", + "InputText3": "Если вам нужна помощь в выяснение того, что входной тип Вашей камеры вы можете посмотреть в камеры URL-адреса в списке на шиноби сайт.", + "Invalid JSON": "Недопустимый Формат json", + "InvalidJSONText": "Пожалуйста, убедитесь, что это действительный json-строку для конфигурации шиноби монитор.", + "JPEG": "В формате JPEG", + "JPEG (Auto Enables JPEG API)": "В формате JPEG (авто позволит использовать API в формате JPEG)", + "JPEG API": "В формате JPEG интерфейс API снимка (цги-бин)", + "JPEG Error": "Ошибка формата JPEG", + "JPEG Mode": "JPEG режим", + "JPEGErrorText": "Возникла проблема получения данных с камеры.", + "Leave blank for random.": "Оставьте пустым для случайных.", + "Left": "Левый Адрес", + "Left Stop": "Левый стоп URL-Адрес", + "Less Than": "Меньше", + "Less Than or Equal to": "Меньше или равно", + "Like": "Как", + "Lisence Plate Detector": "Лицензии Детектор Пластины", + "List Toggle": "Список Тумблер", + "Live Stream Toggle": "Жить Переключения Потока", + "Live View": "Живой Просмотр", + "Local": "Местные", + "Log Level": "Уровень Журнала", + "Log Signal Event": "Журнал сигнал события на стороне клиента только", + "Logging": "Лесозаготовки", + "Login": "Логин", + "Logout": "Выход", + "Logs": "Журналы", + "MB": "МБ", + "MJPEG": "Формат MJPEG", + "MP4 (copy, libx264, libx265)": "МР4 (копия, поддержкой libx264, libx265)", + "MPEG-4 (.mp4 / .ts)": "Формат MPEG-4 (.МР4 / .ТС)", + "MailError": "Mail ошибка : не удалось отправить письмо, проверьте конф.в json. Пропуская какие-либо функции, опираясь на рассылки.", + "Matches": "Матчи", + "Max Storage Amount": "Памяти Макс. объем в мегабайтах", + "Mode": "Режим", + "Monitor": "Монитор", + "Monitor Added by user": "Монитор, добавленные пользователем.", + "Monitor Capture Rate": "Монитор скорости захвата (ФПС)", + "Monitor Groups": "Мониторинг Групп", + "Monitor ID": "Идентификатор монитора", + "Monitor Idling": "Монитор Простаивания", + "Monitor Name": "Имя Монитора", + "Monitor Settings": "Настройки Монитора", + "Monitor Stopped": "Монитор Перестал", + "Monitor Updated by user": "Монитор обновляться пользователем.", + "Monitor mode changed": "Режим монитора меняется", + "Monitor mode is already": "Режим монитора уже", + "Monitor or Key does not exist.": "Монитор или ключ не существует.", + "MonitorIdlingText": "Монитор сессии был заказан на холостом ходу.", + "MonitorStoppedText": "Монитор сеансов было приказано прекратить.", + "Monitors": "Мониторы", + "Monitors per row": "Мониторы на строку для монтажа", + "Montage": "Фотомонтаж", + "Motion GUI": "ГУЙ движения", + "Motion Meter": "Метр Движения", + "Name": "Название", + "No": "Нет", + "No Audio": "Нет Звука", + "No Data": "Нет Данных", + "No Events found for this video": "Не для этого видео", + "No Group with this key exists": "Ни одна группа с таким ключом существует", + "No Monitor Found, Ignoring Request": "Нет Монитор Нашли, Игнорируя Просьбу", + "No Rotation": "Нет Вращения", + "No such file": "Нет такого файла", + "NoMotionEmailText1": "Нет движения", + "NoMotionEmailText2": "Не было никакого движения на камеру", + "NoVideosFoundForDateRange": "Не нашла видео в этот диапазон дат. Попробуйте установить дату начала дальше.", + "Not Authorized": "Не Разрешено", + "Not Connected": "Не Подключен", + "Not Equal to": "Не равны", + "Not In": "Не В", + "Not Matches": "Не Соответствует", + "Not Permitted": "Не Допускается", + "Not an Administrator Account": "Не является учетной записью администратора", + "NotAuthorizedText1": "Не разрешенные, представить команду init с \"авт\",\"ке\" и \"юид\"", + "Notes": "Примечания", + "NotesPlacholder": "Комментарии Вы хотите оставить на этом настройки камеры.", + "Number of Days to keep": "Количество дней хранения", + "ONVIF": "Стандарт onvif", + "ONVIF Scanner": "Сканер стандарта onvif", + "ONVIFnote": "Откройте стандарт onvif устройств за пределами вашей сети или оставьте его пустым для сканирования сети.
Имя пользователя и пароль можно оставить пустым.", + "OpenCV Cascades": "В Формате Opencv Каскада", + "Order Streams": "Потоки Заказов", + "Output Method": "Способ Вывода", + "Password": "Пароль", + "Password Again": "Пароль Еще Раз", + "Passwords don't match": "Пароли не совпадают", + "Paste JSON here.": "Вставить json здесь.", + "Path": "Путь", + "Permissions": "Разрешения", + "Points": "Точки при добавлении точек, щелкните на краю полигона.", + "Port": "Порт", + "Position X": "Положение X", + "Position Y": "Позиция Y", + "Power Video Viewer": "Питания Видео Просмотра", + "Power Viewer": "Зритель Власти", + "Preferences": "Предпочтения", + "Preset": "Предустановленные", + "Probe Size": "Размер Зонда", + "Process Crashed for Monitor": "Процесс разбился на монитор", + "Process Unexpected Exit": "Процесс Неожиданный Выход", + "Profile": "Профиль", + "Quality": "Качество 1 высота, 23 низкий", + "Query": "Запрос", + "RAM": "Оперативной памяти", + "RTSP": "Протокол RTSP", + "RTSP Transport": "РЦП транспорта", + "Range or Single": "Диапазон или один", + "Rate": "Скорость (кадров в секунду)", + "Record": "Запись", + "Record File Type": "Тип Записи Файла", + "Record Height": "Рекордную Высоту", + "Record Video Filter": "Запись Видео Фильтр", + "Record Width": "Запись Ширина", + "Recording": "Запись", + "Recording Flags": "Запись Флаги", + "Recording Segment Interval": "Запись сегмента интервала в минутах", + "Recording Timeout": "Запись тайм-аута в минутах", + "Recording Timestamp": "Метки Записи", + "Recording Watermark": "Запись Водяной Знак", + "RecordingText": "Рекомендуется установить рекорд типа файла в формате WebMи MP4 и видео кодеков для libvpxкопия или поддержкой libx264 потому что твой ввод Тип имеет значение .", + "Refresh List of Cascades": "Обновить список каскадов", + "Region Editor": "Редактор Области", + "Region Name": "Название Области", + "RegionNote": "Точки сохраняются только при нажатии Сохранить на монитор настройки окна.", + "Regions": "Регионы", + "Remember Me": "Запомнить Меня", + "Reset Timer": "Сброс Таймера", + "Restarting Process": "Процесс Перезагрузки", + "Retry Connection": "Повторить попытку подключения несколько раз допустить провала", + "Retrying...": "Повторение...", + "Right": "Правильный URL-Адрес", + "Right Stop": "Право прекратить URL-Адрес", + "Rotate": "Повернуть", + "Save": "Сохранить", + "Save Directory": "Сохранить Каталог", + "Save Events to SQL": "Сохранять события в SQL", + "Save Log in SQL": "Сохранить журнал в SQL это может быстро заполняются.", + "Save as": "Сохранить как", + "Saved Filters": "Сохраненные Фильтры", + "Scan Settings": "Параметры Сканирования", + "Search": "Поиск", + "Send Frames": "Отправить кадры пуш-периодах для анализа", + "Separate with commas, no spaces": "Отделить запятыми, без пробелов", + "Set to Watch Only": "Установить, чтобы смотреть только", + "Settings": "Параметры", + "Settings Changed": "Настройки Изменились", + "SettingsChangedText": "Ваши настройки были сохранены и применены.", + "Shinobi": "Шиноби", + "Shinobi Streamer": "Шиноби Серпантин", + "Show Logs": "Показать Журналы", + "Silent": "Молчит", + "Simple": "Простой", + "Size (mb)": "Размер (Мб)", + "Snapshot": "Снимок", + "Snapshot Flags": "Снимок Флаги", + "Snapshots": "Снимки", + "Sort By": "Сортировать По", + "Start": "Начать", + "Start Recording": "Начать Запись", + "Start Time": "Время Начала", + "Started": "Начал", + "Status Indicator": "Индикатор Состояния", + "Stop URL": "Остановить URL", + "Stream": "Поток", + "Stream Flags": "Флаги Трансляция", + "Stream Timestamp": "Метка Поток", + "Stream Type": "Тип Потока", + "Stream Watermark": "Водяной Поток", + "Stream to YouTube": "Трансляцию на YouTube", + "Stream to YouTube Flags": "Поток флаги на YouTube", + "StreamText": "

В этом разделе будет указать основной поток метода и его параметров. Этот поток будет отображаться на приборной панели. Если вы решите использовать ЗОЖ, в формате JPEG или MJPEG, то вы можете потреблять поток через другие программы.

В формате JPEG потока, по сути, выключает основной поток и использует моментальный снимок ящика, чтобы получить кадры.

", + "Streamer": "Серпантин", + "Streams": "Потоки", + "Superuser": "Суперпользователя", + "Switch on for Still Image": "Переключиться на еще изображения", + "TCP": "Протокол TCP", + "Text Box Color": "Цвет Текстового Поля", + "Text Color": "Цвет Текста", + "Time-lapse": "Промежуток времени", + "Time-lapse Tool": "Инструмент покадровой", + "Timeout": "Ожидания", + "Timeout Reset on Next Motion": "Таймаут сброса на следующем движении", + "Toggle Sidebar": "Переключение Боковой Панели", + "Top Left": "Верхний Левый", + "Top Right": "Вверху Справа", + "Trigger Record": "Триггер Записи", + "Trigger Successful": "Триггер Успешным", + "UDP": "УДП", + "URL": "URL-адрес", + "URL Stop Timeout": "Адрес останавливать время ожидания запуска остановки URL после x миллисекунд", + "US": "Нам", + "Unable to Launch": "Не удалось запустить", + "UnabletoLaunchText": "Пожалуйста, сохраните сначала новый монитор. Затем попытаться запустить редактор регионе.", + "Up": "До URL-Адрес", + "Up Stop": "До остановки URL-Адрес", + "Username": "Имя пользователя", + "Value": "Значение", + "Video": "Видео", + "Video Codec": "Видеокодек", + "Video Filter": "Видеофильтра", + "Video Finished": "Видео Закончил", + "Video Length (minutes) and Motion Count per video": "Продолжительность видео (минут) и движения на видео", + "Video Record Rate": "Видео Скорость записи (кадров в секунду)", + "Video Status": "Статус Видео", + "Video and Time Span (Minutes)": "Прямая и отрезок времени (минут)", + "Videos": "Видео", + "Videos List": "Видео Список", + "Watch": "Смотреть", + "Watch Only": "Смотреть Только", + "WebDAV": "Протокол WebDAV", + "WebM (libvpx)": "Колсоном (libvpx)", + "Webdav Error": "Ошибка В WebDAV", + "WebdavErrorText": "Не удается сохранить. Вы сделали камеры папки внутри выбранной сохранить каталог?", + "Webhook": "Веб-перехватчик", + "Webhook URL": "URL-адрес веб-перехватчик", + "Width": "Ширина", + "Yes": "Да", + "Zoom In": "Зум в URL-Адрес", + "Zoom In Stop": "Зум в URL-Адрес", + "Zoom Out": "Уменьшать URL-Адрес", + "Zoom Out Stop": "Уменьшать остановка URL-Адрес", + "a day": "в день", + "a few seconds": "несколько секунд", + "a minute": "минуту", + "a month": "месяц", + "a year": "год", + "aac": "ААС", + "aac (Default)": "ААС (по умолчанию)", + "ac3": "АС3", + "ago": "назад", + "an hour": "час", + "blankPassword": "Оставьте поле пустым, чтобы сохранить тот же пароль", + "calendar": "календарь", + "clientStreamFailedattemptingReconnect": "На стороне клиента проверить ctream не удалось, попытка воссоединиться.", + "confirmDeleteFilter": "Вы действительно хотите удалить этот фильтр? Нельзя восстановить.", + "copy": "копия", + "days": "дней", + "dropBoxSuccess": "Успехов! Файлы, сохраненные в Dropbox.", + "for Global Access": "для глобального доступа", + "hours": "часов", + "in": "в", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis были (по умолчанию)", + "libvpx (Default)": "libvpx (по умолчанию)", + "libvpx-vp9": "libvpx-vp9 или", + "libx264": "поддержкой libx264", + "libx264 (Default)": "поддержкой libx264 (по умолчанию)", + "libx265": "libx265", + "minutes": "минут", + "modifyVideoText1": "Метод не существует. Убедитесь, что последнее значение URL является не пустым.", + "monitorEditFailedMaxReached": "Ваша учетная запись, достигнуто Максимальное число камер, которые могут быть созданы. Поговорить с администратором, если вы хотели бы это изменить.", + "monitorEditText1": "Неверные данные, проверьте, чтобы увидеть это допустимая строка импорт.", + "monitorEditText2": "Поврежденных Деталей Строку. Проверьте, это json-строку, а не обычный объект был принят.", + "monitorGetText1": "неполный запрос, удалить последний слеш в URL или положить приемлемой стоимости.", + "months": "месяцев", + "noSpecialCharacters": "Без пробелов или специальных символов.", + "on": "на", + "on Error": "в случае ошибки", + "startUpText0": "проверка размера для видео", + "startUpText1": "конец проверить Размер для видео", + "startUpText2": "все пользователи проверены, подождите закрывать открытые файлы и удалить файлы через лимит пользователей", + "startUpText3": "ждал недостроенный видео проверяем какое-то время. 3 секунды.", + "startUpText4": "начиная все мониторы установить для просмотра и записи", + "startUpText5": "Шиноби готов.", + "superAdminText": "\"супер.в json\" не существует. Пожалуйста, переименуйте \"супер.образец.в json\" на \"супер.в json\".", + "superAdminTitle": "Шиноби : Супер Админ", + "total": "общая", + "updateKeyText1": "\"updateKey\" отсутствует \"конф.с json\", нельзя делать обновление таким образом, пока вы не добавите его.", + "updateKeyText2": "\"updateKey\" - это неправильно.", + "years": "лет" +} diff --git a/languages/zh.json b/languages/zh.json new file mode 100644 index 0000000..7dbfcd0 --- /dev/null +++ b/languages/zh.json @@ -0,0 +1,496 @@ +{ + "\"No Motion\" Detector": "\"不运动\"探测器", + "# of Allow MJPEG Clients": "# of Allow MJPEG Clients 0 for infinite", + "180 Degrees": "180度", + "2-Factor Authentication": "2因素认证", + "90 Clockwise": "90顺时针", + "90 Clockwise and Vertical Flip": "90顺时针方向和垂直翻转", + "90 Counter Clockwise and Vertical Flip (default)": "90逆时针方向和垂直翻转的(默认)", + "API": "API", + "API Key Added": "API关键的加入", + "API Key Deleted": "API关键删除", + "API Keys": "API钥匙", + "APIKeyAddedText": "你可以用这个关键。", + "APIKeyDeletedText": "关键已被删除。 它将不再起作用。", + "ASC": "ASC", + "Account Info": "帐户信息", + "AccountEditText1": "不可能编辑。 刷新页面,如果问题继续进行。", + "Accounts": "帐户", + "Action for Selected": "行动选择", + "Add": "添加", + "Add Monitor": "增加监视", + "Add New": "添加新的", + "Admin": "管理员", + "Advanced": "先进的", + "Again": "再一次", + "All Monitors": "所有监视器", + "All Monitors and Privileges": "所有监视和特权", + "All Warnings": "所有的警告", + "Allow Next Command": "允许下一个命令 在分钟", + "Allow Next Email": "允许下电子邮件 在几分钟", + "Allow Next Trigger": "允许下一个触发 在毫秒", + "Allowed IPs": "允许IPs", + "Analyzation Duration": "分析的持续时间", + "Archive": "存档", + "Audio Codec": "音频编", + "Authenticate": "进行身份验证", + "Auto": "汽车", + "Autosave": "自动保存", + "Base64 over Websocket": "Base64过Websocket", + "Bottom Left": "左下", + "Bottom Right": "右", + "Browser Console Log": "浏览器控制台的记录", + "CPU": "CPU", + "CPU indicator will not work. Continuing...": "CPU指标将不会的工作。 继续...", + "CSS": "CSS 的风格你的仪表板。", + "Calendar": "日历", + "Camera Password": "摄像机的密码", + "Camera Username": "摄像机的用户名", + "Camera is not recording": "摄像机是不是记录", + "CameraNotRecordingText": "设置可能不相容的。 检查编码器。 重新启动...", + "Can Control Monitors": "可以控制的监视器", + "Can Delete Videos": "可以删除的视频", + "Can Delete Videos and Events": "可以删除的视频和活动", + "Can Edit Monitor": "可以编辑监控", + "Can Get Logs": "可以得到日志", + "Can Get Monitors": "可以得到监视", + "Can View Monitor": "可以查看监视器", + "Can View Snapshots": "可以查看的快照", + "Can View Streams": "可以看流", + "Can View Videos": "可以观看视频", + "Can View Videos and Events": "可以观看视频和活动", + "Can't Connect": "无法连接", + "Center": "中心 的URL地址", + "Chat on Discord": "聊天上的不和谐", + "Check": "检查", + "Check Signal Interval": "检查信号的时间间隔 在分钟", + "Check for Motion First": "检查运动的第一个", + "Close": "靠近", + "Closed": "关闭", + "Command": "命令", + "Command on Trigger": "命令触发", + "Complete Stream URL": "完整的流网址", + "Confirm": "确认", + "Connected": "连接", + "Connection Type": "连接类型", + "Control": "控制", + "Control Error": "控制误差", + "ControlErrorText1": "控制没有启用", + "Controllable": "可控的", + "Country of Plates": "国家的板", + "Counts of Motion": "项运动", + "Current": "电流", + "Currently viewing": "目前的观察", + "Custom": "定义", + "Custom Base URL": "定义基地址 留下的空白使用主机URL", + "DB Lost.. Retrying..": "数据库丢失。。重试..", + "DESC": "DESC", + "Dashboard": "仪表板", + "Dashboard Language": "仪表板语言", + "Dashcam": "行车记录仪", + "Dashcam (Streamer v2)": "行车记录仪(流v2)", + "Date Range": "日期范围", + "Debug": "调试", + "Default": "默认的", + "Delete": "删除", + "Delete Filter": "删除过滤器", + "Delete Matches": "删除匹配", + "Delete Monitor": "删除监控器", + "Delete Motionless Video": "删除一动不动的视频", + "Delete Motionless Videos (Record)": "删除一动不动的视频(记录)", + "Delete Selected Videos": "删除选择的视频", + "Delete Video": "删除的视频", + "Delete selected": "删除选择", + "DeleteMonitorText": "你想要删除这个监视器吗? 你不能恢复。 该文件为这个ID将保留在文件系统。 如果你选择重新建立一个监测与同一标识的影片和事件将变得可见,在仪表板。", + "DeleteSelectedVideosMsg": "你想要删除这些视频? 你不能恢复他们。", + "DeleteVideoMsg": "你想要删除这个视频? 你不能恢复。", + "Deleted": "已删除", + "Detect Objects": "检测对象, 见下", + "Detector": "探测器", + "Detector Flags": "探测器的标志", + "Detector Rate": "检测率 (》)", + "DetectorText": "

当宽度和高度框显示,你应该将它们设置为640x480或以下。 这将优化该阅读的速度框架。

", + "Disable Night Vision": "禁止夜视 的URL地址", + "Disable Nightvision": "禁止夜视", + "Disabled": "残疾人", + "Documentation": "文档", + "Don't show this anymore": "不再这样下去了", + "Double Quote Directory": "双引目录中的 一些目录具有空间。 使用这个可能会崩溃,一些摄像机。", + "Down": "下 URL地址", + "Down Stop": "下站 的URL地址", + "Download": "下载", + "EU": "欧盟", + "Edit": "编辑", + "Email": "电子邮件", + "Email Details": "电子邮件的细节", + "Email on No Motion": "电子邮件上的\"不动\"", + "Email on Trigger": "电子邮件,在触发 的电子邮件去的主要账户持有人的登录地址。", + "Enable Night Vision": "启用夜视 的URL地址", + "Enable Nightvision": "启用夜视", + "Enabled": "启用", + "End": "结束", + "End Time": "结束的时间", + "Ended": "结束", + "Enlarge": "放大", + "Enter this code to proceed": "输入这个代码来进入", + "Equal to": "等于", + "Error Connecting": "错误的连接", + "Event": "事件", + "Event Limit": "事件的限制", + "EventText1": "触发事件在运动", + "EventText2": "不能电子邮件的图像、文件是不可访问", + "Events": "事件", + "Example": "例", + "Execute Command": "执行命令", + "Executed": "执行", + "Export": "出口", + "FFmpegCantStart": "。不能开始", + "FFmpegCantStartText": "记录的引擎这摄像机不能开始。 有可能是错误的东西与你的摄像机的配置。 如果有任何记录其他比这个请帖子他们在该 问题 上的审查中。", + "FFmpegTip": "FFprobe是一个简单的多媒体流的分析仪。 你可以用它来输出的所有种类的信息输入其中包括持续时间,框率,框架大小,等等。", + "FFprobe": "探针", + "FactorAuthText1": "该守则将只是活跃的15分钟。 如果你再次登录的计时器将是重要15分钟用相同的代码。", + "Fatal": "致命的", + "Fatal Maximum Reached": "致命达到最大,停止摄像机。", + "FatalMaximumReachedText": "JPEG误差是致命的。", + "Feed-in Image Height": "在图像的高度", + "Feed-in Image Width": "在图像的宽度", + "Fields cannot be empty": "田不可能是空的", + "File Not Exist": "文件不存在", + "File Not Found": "找不到的文件", + "File Type": "文件的类型", + "FileNotExistText": "无法保存不存在的文件。 事了。", + "Filename": "文件名", + "Filesize": "Filesize", + "Filter ID": "过滤器ID", + "Filter Matches": "过滤器匹配", + "Filter Name": "过滤器名称", + "FilterMatchesText1": "这个过滤器已经满足的条件。", + "FilterMatchesText2": "视频发现。", + "Filters": "过滤器", + "Filters Updated": "过滤器更新", + "FiltersUpdatedText": "你有了变化保存和应用。", + "Find Where": "找到那里", + "Fix": "修复", + "Fix Video": "解决视频", + "FixVideoMsg": "你要修补这个视频? 你不能撤消这种行动。", + "Font Path": "字体路径", + "Font Size": "字体大小", + "Force Port": "部队口", + "Found Devices": "设备找到了", + "Frame Rate": "框率 (》)", + "Full Frame Detection": "完全检测框架", + "Fullscreen": "全屏", + "Greater Than": "大于", + "Greater Than or Equal to": "大于或等于", + "Group Key": "小组密", + "Group Name": "小组的名字", + "Grouping": "分组 ", + "H.264 / H.265 / H.265+": "H.264/H.265/H.265 ", + "HLS (.m3u8)": "高级别(中。m3u8)", + "HLS (includes Audio)": "高级别(包括音频)", + "HLS Audio Encoder": "高级别声音编码器", + "HLS List Size": "高级别列出的大小", + "HLS Preset": "高级别预先设定", + "HLS Segment Length": "高级别段的长度 在几秒钟内", + "HLS Video Encoder": "高级别编码视频", + "HTTP": "HTTP", + "HTTPS": "HTTPS", + "Height": "高度", + "Help": "帮助", + "Hide List": "隐藏列表中的", + "Hide Notes": "隐藏的笔记", + "Host": "主机", + "Hotswap Modes (Watch-Only)": "热交换模式(看-Only)", + "How to Record": "如何记录", + "IP Address": "IP地址", + "Identity": "身份", + "IdentityText1": "这是系统将如何识别数据为这个流。 你不能改变的 监测ID 一旦你必须按下保存。 如果你想你可以使 监测ID 更多的人阅读,然后再继续。", + "IdentityText2": "你可以重复一个监测通过修改 监测ID 然后按下保存。 你 不能 使用的标识一个监视已经存在或者它将存在于监测的数据库信息。", + "Idle": "空闲", + "Image Height": "像高", + "Image Location": "图像的位置 绝对路径或留下的空白使用全球", + "Image Position": "图像的位置", + "Image Width": "图像的宽度", + "Import": "进口", + "Import Monitor Configuration": "进口监测器的配置", + "ImportMonitorConfigurationText": "这样做将overrwrite任何改变目前没有保存。 进口的变化将只适用于当按 保存人。", + "In": "在", + "Incorrect Settings Chosen": "设置不正确的选择", + "Indifference": "冷漠", + "Input": "输入", + "Input Flags": "输入的标志", + "Input Type": "输入型", + "InputText1": "这部分告诉忍如何消耗流。 最佳性能试图调整你的摄像机的内置。 找到以下选项,并设定他们如图所示。 找到你的摄像机可以使用 建立在升扫描仪 的忍者. 一些升摄像机要求采用一个管理工具,以修改其内部设置。 如果你找不到你的摄像机你可以尝试 提升设备Manager for Windows.", + "InputText2": "
  • Framerate(》): 高:10-15》,低:2-5》
  • 我框架的时间间隔: 80
  • 比特率类型: 社区康复(恒定的比率)
  • 比特率: 间256kbps-500kbps
", + "InputText3": "如果你需要帮忙找出来是什么样的输入型你的摄像机是你可以看看 摄像机的Url清单 上的忍者的网站。", + "Invalid JSON": "无效JSON", + "InvalidJSONText": "请确保这是一个有效的JSON串忍监测配置。", + "JPEG": "JPEG", + "JPEG (Auto Enables JPEG API)": "JPEG(自动使JPEG API)", + "JPEG API": "JPEG API 快照(cgi-bin)", + "JPEG Error": "JPEG错误", + "JPEG Mode": "JPEG模式", + "JPEGErrorText": "有一个问题获得数据从你的相机。", + "Leave blank for random.": "留下的空白。", + "Left": "左 URL地址", + "Left Stop": "左站 的URL地址", + "Less Than": "不到", + "Less Than or Equal to": "小于或等于", + "Like": "喜欢", + "Lisence Plate Detector": "图编辑功能板检测器", + "List Toggle": "列表中切换", + "Live Stream Toggle": "现场流肘", + "Live View": "现场查看", + "Local": "本地", + "Log Level": "日志的水平", + "Log Signal Event": "登录信号的事件, 客户只有一侧", + "Logging": "日志记录", + "Login": "登录", + "Logout": "注销", + "Logs": "日志", + "MB": "MB", + "MJPEG": "安全监控", + "MP4 (copy, libx264, libx265)": "MP4(副本,libx264,libx265)", + "MPEG-4 (.mp4 / .ts)": "MPEG-4(中。mp4/.ts)", + "MailError": "邮件错误:不能发送电子邮件、检查conf.手机中。 跳过的任何功能的依赖邮寄。", + "Matches": "比赛", + "Max Storage Amount": "最大储存量 在兆", + "Mode": "模式", + "Monitor": "监视器", + "Monitor Added by user": "监控中加入的用户。", + "Monitor Capture Rate": "监测捕获率 (》)", + "Monitor Groups": "监测组", + "Monitor ID": "监测ID", + "Monitor Idling": "监测空转", + "Monitor Name": "监视器名称", + "Monitor Settings": "监测设置", + "Monitor Stopped": "监测停止", + "Monitor Updated by user": "监测更新用户。", + "Monitor mode changed": "监视器模式的改变", + "Monitor mode is already": "监视器模式已经", + "Monitor or Key does not exist.": "监视器或关键并不存在。", + "MonitorIdlingText": "监测会议已订于空闲。", + "MonitorStoppedText": "监测会议已被下令停止。", + "Monitors": "监视器", + "Monitors per row": "监视器,每行 为的蒙太奇", + "Montage": "蒙太奇", + "Motion GUI": "运动GUI", + "Motion Meter": "运动米", + "Name": "名称", + "No": "没有", + "No Audio": "没有音频", + "No Data": "没有数据", + "No Events found for this video": "没事的找到这个视频", + "No Group with this key exists": "没有任何组织这个关键的存在", + "No Monitor Found, Ignoring Request": "没有监视器发现,忽略了请求", + "No Rotation": "没有旋转", + "No such file": "没有这样的文件", + "NoMotionEmailText1": "没有运动", + "NoMotionEmailText2": "没有任何运动检测摄像机", + "NoVideosFoundForDateRange": "没有视频发现在这的日期范围。 试图设置,开始日期进一步回。", + "Not Authorized": "没有授权", + "Not Connected": "不连接", + "Not Equal to": "不等于", + "Not In": "不在", + "Not Matches": "不匹配", + "Not Permitted": "不允许", + "Not an Administrator Account": "不是管理员的帐户", + "NotAuthorizedText1": "没有授权,提交init命令与\"授权\",\"科\",并\"uid\"", + "Notes": "注意到", + "NotesPlacholder": "评论你想离开这个相机设置。", + "Number of Days to keep": "保留的天数", + "ONVIF": "升", + "ONVIF Scanner": "升扫描仪", + "ONVIFnote": "发现提升设备网络之外自己或留下的空白以扫描你的前的网络。
用户名和密码可以留空。", + "OpenCV Cascades": "该版本的瀑布", + "Order Streams": "顺流", + "Output Method": "输出方法", + "Password": "密码", + "Password Again": "再次密码", + "Passwords don't match": "密码不匹配", + "Paste JSON here.": "贴JSON在这里。", + "Path": "路径", + "Permissions": "权限", + "Points": "点 在添加点击边缘上的多边形。", + "Port": "口", + "Position X": "X位置", + "Position Y": "Y位置", + "Power Video Viewer": "的电视观众", + "Power Viewer": "电观众", + "Preferences": "喜好", + "Preset": "预先设定", + "Probe Size": "探头大小", + "Process Crashed for Monitor": "进程崩溃的监视器", + "Process Unexpected Exit": "处理意想不到的退出", + "Profile": "配置文件", + "Quality": "质量 1高,23低", + "Query": "查询", + "RAM": "RAM", + "RTSP": "RTSP", + "RTSP Transport": "RTSP运输", + "Range or Single": "范围内或单", + "Rate": "率 (》)", + "Record": "记录", + "Record File Type": "记录文件的类型", + "Record Height": "记录的高度", + "Record Video Filter": "视频录制的过滤器", + "Record Width": "记录宽度", + "Recording": "记录", + "Recording Flags": "记录的标志", + "Recording Segment Interval": "记录段时间间隔 在分钟", + "Recording Timeout": "记录超时 在分钟", + "Recording Timestamp": "记录时间戳", + "Recording Watermark": "记录水印", + "RecordingText": "它建议设置 的记录文件的类型DivxMP4视频编libvpx复制或 libx264 因为你的 输入型 设置 的。", + "Refresh List of Cascades": "刷新名单的瀑布", + "Region Editor": "地区编辑器", + "Region Name": "地区名称", + "RegionNote": "点只保存,当你按下 保存监测器设置 窗口。", + "Regions": "区域", + "Remember Me": "还记得我", + "Reset Timer": "重置计时器", + "Restarting Process": "重新启动进程", + "Retry Connection": "试连接 的次数,允许失败", + "Retrying...": "重新尝试...", + "Right": "正确的 URL地址", + "Right Stop": "右站 的URL地址", + "Rotate": "旋转", + "Save": "保存", + "Save Directory": "保存目录", + "Save Events to SQL": "保存活动SQL", + "Save Log in SQL": "保存记录在SQL 这可以迅速填补的。", + "Save as": "保存", + "Saved Filters": "保存的过滤器", + "Scan Settings": "扫描设置", + "Search": "搜索", + "Send Frames": "送框架 推框架进行分析", + "Separate with commas, no spaces": "独立使用逗号,不空间", + "Set to Watch Only": "设置只观看", + "Settings": "设置", + "Settings Changed": "设置改变", + "SettingsChangedText": "你的设置已保存和应用。", + "Shinobi": "忍者", + "Shinobi Streamer": "忍流光", + "Show Logs": "日志显示", + "Silent": "沉默", + "Simple": "简单的", + "Size (mb)": "小(mb)", + "Snapshot": "快照", + "Snapshot Flags": "快照标志", + "Snapshots": "快照", + "Sort By": "排序", + "Start": "开始", + "Start Recording": "开始记录", + "Start Time": "开始的时间", + "Started": "开始", + "Status Indicator": "状态指示器", + "Stop URL": "停止URL", + "Stream": "流", + "Stream Flags": "流的标志", + "Stream Timestamp": "流的时间戳", + "Stream Type": "流的类型", + "Stream Watermark": "流水印", + "Stream to YouTube": "流到YouTube", + "Stream to YouTube Flags": "流到YouTube的标志", + "StreamText": "

这部分会指定主流的方法和它的设置。 这种流将显示在仪表板。 如果你选择使用高级别、JPEG或数然后你就可以占用的流通过其他程序。

使用JPEG流基本上关闭主流和使用的快照站获得的框架。

", + "Streamer": "经幡", + "Streams": "流", + "Superuser": "超级用户", + "Switch on for Still Image": "开关于仍然图像", + "TCP": "TCP", + "Text Box Color": "文本框颜色", + "Text Color": "文字颜色", + "Time-lapse": "时间流逝", + "Time-lapse Tool": "延时的工具", + "Timeout": "超时", + "Timeout Reset on Next Motion": "超时的重置上下运动", + "Toggle Sidebar": "切换边栏", + "Top Left": "左上", + "Top Right": "右上方", + "Trigger Record": "触发记录", + "Trigger Successful": "触发成功的", + "UDP": "UDP", + "URL": "URL", + "URL Stop Timeout": "URL停止超时 停止运行URL后X毫秒", + "US": "我们", + "Unable to Launch": "无法启动", + "UnabletoLaunchText": "请保存的新的监测第一次。 然后试图启动该地区编辑器。", + "Up": "立 URL地址", + "Up Stop": "起来站 的URL地址", + "Username": "用户名", + "Value": "值", + "Video": "视频", + "Video Codec": "视频编", + "Video Filter": "视频的过滤器", + "Video Finished": "视频完成", + "Video Length (minutes) and Motion Count per video": "视频度(分钟)和运动的计每视频", + "Video Record Rate": "视频记录速率 (》)", + "Video Status": "视频状态", + "Video and Time Span (Minutes)": "视频和时间跨度(分钟)", + "Videos": "视频", + "Videos List": "视频清单", + "Watch": "看", + "Watch Only": "只观看", + "WebDAV": "WebDAV", + "WebM (libvpx)": "Divx(libvpx)", + "Webdav Error": "Webdav错误", + "WebdavErrorText": "不能保存。 你使摄像文件夹在你选择的保存目录?", + "Webhook": "两者", + "Webhook URL": "两者URL", + "Width": "宽", + "Yes": "是的", + "Zoom In": "放大 的URL地址", + "Zoom In Stop": "放大停止 URL地址", + "Zoom Out": "缩小 的URL地址", + "Zoom Out Stop": "缩小站 的URL地址", + "a day": "一天", + "a few seconds": "几秒钟", + "a minute": "一分钟", + "a month": "一个月", + "a year": "一年", + "aac": "aac", + "aac (Default)": "aac(默认)", + "ac3": "ac3", + "ago": "前", + "an hour": "一个小时", + "blankPassword": "留下的空白,以保持同一个密码", + "calendar": "日历", + "clientStreamFailedattemptingReconnect": "客户的侧ctream检查失败,试图重新连接。", + "confirmDeleteFilter": "你想要删除这个过滤器? 你不能恢复。", + "copy": "复制", + "days": "天", + "dropBoxSuccess": "成功! 文件保存到您的序。", + "for Global Access": "全球访问", + "hours": "小时", + "in": "在", + "libmp3lame": "libmp3lame", + "libopus": "libopus", + "libvorbis (Default)": "libvorbis(默认)", + "libvpx (Default)": "libvpx(默认)", + "libvpx-vp9": "libvpx-vp9", + "libx264": "libx264", + "libx264 (Default)": "libx264(默认)", + "libx265": "libx265", + "minutes": "分钟", + "modifyVideoText1": "方法并不存在。 检查,以确保最后的价值的网址是没有空白。", + "monitorEditFailedMaxReached": "你的账户已经达到最大数量的摄像机,可以创建。 说话给管理员如果你想这改变。", + "monitorEditText1": "无效数据后,检查看看,这是一个有效的进口串。", + "monitorEditText2": "无效的细节串。 检查看看它是一个JSON串并不是一个普通的物体被通过。", + "monitorGetText1": "不完整的请求,删除最后一条斜线网址,或把接受的价值。", + "months": "几个月", + "noSpecialCharacters": "没有空间或特殊字符。", + "on": "上", + "on Error": "在错误", + "startUpText0": "尺寸检查的视频", + "startUpText1": "终端的尺寸检查的视频", + "startUpText2": "所有用户的检查,等待关闭打开文件,并删除文件的用户限制", + "startUpText3": "等着给未完成的视频检查一些时间。 3秒钟。", + "startUpText4": "开始的所有监视器组,以观察和记录", + "startUpText5": "忍者已准备就绪。", + "superAdminText": "\"超级。json\"不存在。 请重新命名\"超级。样品。json\"到\"超级。json\"。", + "superAdminTitle": "忍:超级管理员", + "total": "总", + "updateKeyText1": "\"updateKey\"缺失\"conf.json\",无法做更新这样直到你加入它。", + "updateKeyText2": "\"updateKey\"是不正确的。", + "years": "年" +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..badfe02 --- /dev/null +++ b/package.json @@ -0,0 +1,44 @@ +{ + "name": "shinobi", + "version": "1.0.37", + "description": "CCTV and NVR in Node.js, Version : daf882caf6053a7c2c8f4e69427620356f8a440c", + "main": "camera.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "chmod +x INSTALL/start.sh && INSTALL/start.sh" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/moeiscool/Shinobi.git" + }, + "author": "Moe Alam", + "bugs": { + "url": "https://github.com/ShinobiCCTV/Shinobi/issues" + }, + "homepage": "https://github.com/moeiscool/Shinobi#readme", + "dependencies": { + "body-parser": "^1.15.2", + "circular-json": "0.3.1", + "connection-tester": "^0.1.1", + "chokidar": "^2.0.3", + "mp4frag": "^0.0.15", + "ejs": "^2.5.5", + "express": "^4.14.0", + "jsonfile": "^3.0.1", + "moment": "^2.17.0", + "mysql": "^2.12.0", + "knex": "^0.14.2", + "pam-diff": "^0.10.2", + "pipe2pam": "^0.6.2", + "nodemailer": "^4.0.1", + "node-onvif": "^0.1.4", + "path": "^0.12.7", + "request": "^2.79.0", + "socket.io": "^1.7.1", + "socket.io-client": "^1.7.2", + "http-proxy": "^1.17.0", + "webdav": "^0.3.1", + "ldapauth-fork": "^4.0.2" + }, + "devDependencies": {} +} diff --git a/plugins/.gitignore b/plugins/.gitignore new file mode 100644 index 0000000..34613db --- /dev/null +++ b/plugins/.gitignore @@ -0,0 +1,4 @@ +opencv-python +ccv +stemkoski +variantai \ No newline at end of file diff --git a/plugins/child/.gitignore b/plugins/child/.gitignore new file mode 100644 index 0000000..bd55664 --- /dev/null +++ b/plugins/child/.gitignore @@ -0,0 +1,3 @@ +conf.json +events +frames \ No newline at end of file diff --git a/plugins/child/child.js b/plugins/child/child.js new file mode 100644 index 0000000..6b1a17c --- /dev/null +++ b/plugins/child/child.js @@ -0,0 +1,392 @@ +var os = require('os'); +var fs = require('fs'); +var path = require('path'); +var mysql = require('mysql'); +var moment = require('moment'); +var request = require("request"); +var spawn = require('child_process').spawn; +var exec = require('child_process').exec; +var execSync = require('child_process').execSync; +var connectionTester = require('connection-tester'); +var config = require('./conf.json'); + +exec("ps aux | grep -ie ffmpeg | awk '{print $2}' | xargs kill -9");//kill any ffmpeg running +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +s={connected:false,child_node:true,platform:os.platform(),group:{}}; + +//connect to master +io = require('socket.io-client')('ws://'+config.ws); +//spawn conatiner +s.spawns={}; +//emulate master sql query +sql={ + query:function(x,y,z){ + io.emit('c',{f:'sql',query:x,values:y});if(typeof z==='function'){z();} + } +} +//get this nodes cpu usage +s.cpuUsage=function(e){ + k={} + switch(s.platform){ + case'win32': + k.cmd="@for /f \"skip=1\" %p in ('wmic cpu get loadpercentage') do @echo %p%" + break; + case'darwin': + k.cmd="ps -A -o %cpu | awk '{s+=$1} END {print s}'"; + break; + case'linux': + k.cmd='LANG=C top -b -n 2 | grep "^'+config.cpuUsageMarker+'" | awk \'{print $2}\' | tail -n1'; + break; + } + if(config.customCpuCommand){ + exec(config.customCpuCommand,{encoding:'utf8',detached: true},function(err,d){ + if(s.isWin===true) { + d = d.replace(/(\r\n|\n|\r)/gm, "").replace(/%/g, "") + } + e(d) + }); + } else if(k.cmd){ + exec(k.cmd,{encoding:'utf8',detached: true},function(err,d){ + if(s.isWin===true){ + d=d.replace(/(\r\n|\n|\r)/gm,"").replace(/%/g,"") + } + e(d) + }); + } else{ + e(0) + } +} +setInterval(function(){ + s.cpuUsage(function(cpu){ + io.emit('c',{f:'cpu',cpu:parseFloat(cpu)}) + }) +},2000); +//interact with server functions +s.cx=function(x){io.emit('c',x)} +//emulate master socket emitter +s.tx=function(x,y){s.cx({f:'s.tx',data:x,to:y})} +//emulate master logger +s.log=function(x,y){console.log(y);s.cx({f:'s.log',data:s.init('clean',x),to:y})} +//emulate master camera function +s.camera=function(x,y){s.cx({f:'camera',mode:x,data:y})} + +//load camera controller vars +s.nameToTime=function(x){x=x.split('.')[0].split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;} +s.ratio=function(width,height,ratio){ratio = width / height;return ( Math.abs( ratio - 4 / 3 ) < Math.abs( ratio - 16 / 9 ) ) ? '4:3' : '16:9';} +s.gid=function(x){ + if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.moment=function(e,x){if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'};return moment(e).utcOffset('-0800').format(x)} +s.kill=function(x,e,p){ + if(e&&s.group[e.ke].mon[e.id].record){ + clearTimeout(s.group[e.ke].mon[e.id].record.capturing); + if(s.group[e.ke].mon[e.id].record.request&&s.group[e.ke].mon[e.id].record.request.abort){s.group[e.ke].mon[e.id].record.request.abort();delete(s.group[e.ke].mon[e.id].record.request);} + }; + if(!x||x===1){return};if(!x.stdin){return};p=x.pid;x.stdin.pause();setTimeout(function(){x.kill('SIGTERM');delete(x);setTimeout(function(){exec('kill -9 '+p)},1000)},1000) +} +s.cameraVals=function(e){ + e.t=Object.keys(s.group[e.ke].mon[e.id]);e.a={}; + e.t.forEach(function(n){ + if(s.group[e.ke].mon[e.id][n] instanceof Object){e.a[n]=s.group[e.ke].mon[e.id][n]}; + }); + return e.a; +} +//directories +s.group={}; +s.dir={videos:__dirname+'/videos/',frames:__dirname+'/frames/'}; +if (!fs.existsSync(s.dir.frames)){ + fs.mkdirSync(s.dir.frames); +} +if (!fs.existsSync(s.dir.videos)){ + fs.mkdirSync(s.dir.videos); +} +////Camera Controller +s.init=function(x,e){ + switch(x){ + case 0://camera + if(!s.group[e.ke]){s.group[e.ke]={}}; + if(!s.group[e.ke].mon){s.group[e.ke].mon={}} + if(!s.group[e.ke].mon[e.mid]){s.group[e.ke].mon[e.mid]={}} + if(!s.group[e.ke].mon[e.mid].watch){s.group[e.ke].mon[e.mid].watch={}}; + if(e.type==='record'){e.record=1}else{e.record=0} + if(!s.group[e.ke].mon[e.mid].record){s.group[e.ke].mon[e.mid].record={yes:e.record}}; + if(!s.group[e.ke].mon[e.mid].started){s.group[e.ke].mon[e.mid].started={}}; + if(!s.group[e.ke].mon[e.mid].running){s.group[e.ke].mon[e.mid].running={}}; + break; + case'clean': + if(e instanceof Object){ + x={keys:Object.keys(e),ar:{}}; + x.keys.forEach(function(v){ + if(v!=='record'&&v!=='spawn'&&v!=='running'&&(typeof e[v]!=='function')){x.ar[v]=e[v];} + }); + return x.ar; + } + break; + case'url': + //build a complete url from pieces + e.authd=''; + if(e.details.muser&&e.details.muser!==''&&e.host.indexOf('@')===-1) { + e.authd=e.details.muser+':'+e.details.mpass+'@'; + } + if(e.port==80&&e.details.port_force!=='1'){e.porty=''}else{e.porty=':'+e.port} + e.url=e.protocol+'://'+e.authd+e.host+e.porty+e.path;return e.url; + break; + case'url_no_path': + e.authd=''; + if(!e.details.muser){e.details.muser=''} + if(!e.details.mpass){e.details.mpass=''} + if(e.details.muser!==''&&e.host.indexOf('@')===-1) { + e.authd=e.details.muser+':'+e.details.mpass+'@'; + } + if(e.port==80&&e.details.port_force!=='1'){e.porty=''}else{e.porty=':'+e.port} + e.url=e.protocol+'://'+e.authd+e.host+e.porty;return e.url; + break; + } + if(typeof e.callback==='function'){setTimeout(function(){e.callback();delete(e.callback);},2000);} +} +s.video=function(x,e){ + if(!e){e={}}; + if(e.mid){e.id=e.mid}; + switch(x){ + case'delete': + e.dir=s.dir.videos+e.ke+'/'+e.id+'/'; + e.save=[e.id,e.ke,s.nameToTime(e.filename),0]; + sql.query('DELETE FROM Videos WHERE `mid`=? AND `ke`=? AND `time`=? AND `status`=?',e.save) + s.tx({f:'video_delete',reason:'Camera Error',filename:e.filename+'.'+e.ext,mid:e.id,ke:e.ke,time:s.nameToTime(e.filename),end:moment().format('YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke); + if(fs.existsSync(e.dir+e.filename+'.'+e.ext)){ + return fs.unlink(e.dir+e.filename+'.'+e.ext); + } + break; + case'close': + e.dir=s.dir.videos+e.ke+'/'+e.id+'/'; + console.log(e.dir+e.filename+'.'+e.ext) + if(fs.existsSync(e.dir+e.filename+'.'+e.ext)){ + e.filesize=fs.statSync(e.dir+e.filename+'.'+e.ext)["size"]; + if((e.filesize/100000).toFixed(2)>0.25){ + e.save=[e.filesize,e.frames,1,e.id,e.ke,s.nameToTime(e.filename)]; + sql.query('UPDATE Videos SET `size`=?,`frames`=?,`status`=? WHERE `mid`=? AND `ke`=? AND `time`=?',e.save) + fs.readFile(e.dir+e.filename+'.'+e.ext,function (err,data) { + s.cx({f:'created_file',mid:e.id,ke:e.ke,created_file:data,filename:e.filename+'.'+e.ext,d:s.init('clean',e)}); + s.tx({f:'video_build_success',filename:e.filename+'.'+e.ext,mid:e.id,ke:e.ke,time:s.nameToTime(e.filename),size:e.filesize,end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke); + }); + }else{ + s.video('delete',e); + s.log(e,{type:'File Corrupt',msg:{ffmpeg:s.group[e.ke].mon[e.mid].ffmpeg,filesize:(e.filesize/100000).toFixed(2)}}) + } + }else{ + s.video('delete',e); + s.log(e,{type:'File Not Exist',msg:'Cannot save non existant file. Something went wrong.',ffmpeg:s.group[e.ke].mon[e.id].ffmpeg}) + } + break; + } +} +s.ffmpeg=function(e,x){ + if(!x){x={tmp:''}} +// if(!e.details.cutoff||e.details.cutoff===''){x.cutoff=15}else{x.cutoff=parseFloat(e.details.cutoff)};if(isNaN(x.cutoff)===true){x.cutoff=15} +// x.segment=' -f segment -strftime 1 -segment_time '+(60*x.cutoff)+' -segment_format '+e.ext + if(!e.details.timestamp||e.details.timestamp==1){x.time=' -vf drawtext=fontfile=/usr/share/fonts/truetype/freefont/FreeSans.ttf:text=\'%{localtime}\':x=(w-tw)/2:y=0:fontcolor=white:box=1:boxcolor=0x00000000@1:fontsize=10';}else{x.time=''} + switch(e.ext){ + case'mp4': + x.vcodec='libx265';x.acodec='libfaac'; + if(e.details.vcodec&&e.details.vcodec!==''){x.vcodec=e.details.vcodec} + break; + case'webm': + x.acodec='libvorbis',x.vcodec='libvpx'; + break; + } + if(e.details.acodec&&e.details.acodec!==''){x.acodec=e.details.acodec} + if(x.acodec==='none'){x.acodec=''}else{x.acodec=' -acodec '+x.acodec} + if(x.vcodec!=='none'){x.vcodec=' -vcodec '+x.vcodec} + if(e.fps&&e.fps!==''){x.framerate=' -r '+e.fps}else{x.framerate=''} + if(e.details.vf&&e.details.vf!==''){ + if(x.time===''){x.vf=' -vf '}else{x.vf=','} + x.vf+=e.details.vf; + x.time+=x.vf; + } + if(e.details.svf&&e.details.svf!==''){x.svf=' -vf '+e.details.svf;}else{x.svf='';} +// if(e.details.svf){'-vf "rotate=45*(PI/180)'} + switch(e.type){ + case'socket':case'jpeg':case'pipe': + if(!x.vf||x.vf===','){x.vf=''} + x.tmp='-loglevel warning -pattern_type glob -f image2pipe'+x.framerate+' -vcodec mjpeg -i -'+x.vcodec+x.time+x.framerate+' -use_wallclock_as_timestamps 1 -q:v 1'+x.vf+' '+e.dir+e.filename+'.'+e.ext; + break; + case'mjpeg': + if(e.mode=='record'){ + x.watch=x.vcodec+x.time+' -r 10 -s '+e.width+'x'+e.height+' -use_wallclock_as_timestamps 1 -q:v 1 '+e.dir+e.filename+'.'+e.ext+'' + }else{ + x.watch=''; + }; + x.tmp='-loglevel warning -reconnect 1 -f mjpeg -i '+e.url+''+x.watch+' -f image2pipe'+x.svf+' -s '+e.ratio+' pipe:1'; + break; + case'h264': + if(!x.vf||x.vf===','){x.vf=''} + if(e.mode=='record'){ + x.watch=x.vcodec+x.framerate+x.acodec+' -movflags frag_keyframe+empty_moov -s '+e.width+'x'+e.height+' -use_wallclock_as_timestamps 1 -q:v 1'+x.vf+' '+e.dir+e.filename+'.'+e.ext + }else{ + x.watch=''; + }; + x.tmp='-loglevel warning -i '+e.url+' -stimeout 2000'+x.watch+' -f image2pipe'+x.svf+' -s '+e.ratio+' pipe:1'; + break; + case'local': + if(e.mode=='record'){ + x.watch=x.vcodec+x.time+x.framerate+x.acodec+' -movflags frag_keyframe+empty_moov -s '+e.width+'x'+e.height+' -use_wallclock_as_timestamps 1 '+e.dir+e.filename+'.'+e.ext + }else{ + x.watch=''; + }; + x.tmp='-loglevel warning -i '+e.path+''+x.watch+' -f image2pipe'+x.svf+' -s '+e.ratio+' pipe:1'; + break; + } + s.group[e.ke].mon[e.mid].ffmpeg=x.tmp; + return spawn('ffmpeg',x.tmp.split(' ')); +} + +//child functions +var cn={}; +io.on('connect', function(d){ + console.log('connected'); + io.emit('c',{f:'init',socketKey:config.key,u:{name:config.name}}) +}); +io.on('c',function(d){ + console.log(d.f); + switch(d.f){ + case'init_success': + s.connected=true; + s.other_helpers=d.child_helpers; + break; + case'kill': + s.init(0,d.d); + s.kill(s.group[d.d.ke].mon[d.d.id].spawn,d.d) + break; + case'sync': + s.init(0,d.sync); + Object.keys(d.sync).forEach(function(v){ + s.group[d.sync.ke].mon[d.sync.mid][v]=d.sync[v]; + }); + break; + case'delete_file'://delete video + d.dir=s.dir.videos+d.ke+'/'+d.mid+'/'+d.file; + if(fs.existsSync(d.dir)){ + fs.unlink(d.dir); + } + break; + case'close'://close video + s.video('close',d.d); + break; + case'spawn'://start video + s.init(0,d.d); + s.group[d.d.ke].mon[d.d.id]=d.mon; + if(!s.group[d.d.ke].mon_conf){s.group[d.d.ke].mon_conf={}} + if(!s.group[d.d.ke].mon_conf[d.d.id]){s.group[d.d.ke].mon_conf[d.d.id]=s.init('clean',d.d);} + if(s.group[d.d.ke].mon[d.d.id].spawn&&s.group[d.d.ke].mon[d.d.id].spawn.stdin){return} + if(d.d.mode==='record'){ + console.log(s.group[d.d.ke].mon[d.d.id]) + s.group[d.d.ke].mon[d.d.id].record.yes=1; + d.d.dir=s.dir.videos+d.d.ke+'/'; + if (!fs.existsSync(d.d.dir)){ + fs.mkdirSync(d.d.dir); + } + d.d.dir=s.dir.videos+d.d.ke+'/'+d.d.id+'/'; + if (!fs.existsSync(d.d.dir)){ + fs.mkdirSync(d.d.dir); + } + }else{ + s.group[d.d.ke].mon[d.d.mid].record.yes=0; + } + if(d.d.mode==='record'||d.d.type==='mjpeg'||d.d.type==='h264'||d.d.type==='local'){ + s.group[d.d.ke].mon[d.d.id].spawn = s.ffmpeg(d.d); + s.log(d.d,{type:'FFMPEG Process Starting',msg:{cmd:s.group[d.d.ke].mon[d.d.id].ffmpeg}}); + } + d.d.frames=0; + switch(d.d.type){ + case'jpeg': + if(!d.d.details.sfps||d.d.details.sfps===''){ + d.d.details.sfps=parseFloat(d.d.details.sfps); + if(isNaN(d.d.details.sfps)){d.d.details.sfps=1} + } + d.d.captureOne=function(f){ + s.group[d.d.ke].mon[d.d.id].record.request=request({url:d.d.url,method:'GET',encoding: null,timeout:3000},function(er,data){ + ++d.d.frames; if(s.group[d.d.ke].mon[d.d.id].spawn&&s.group[d.d.ke].mon[d.d.id].spawn.stdin){ + if(er){ + ++d.d.error_count; + s.log(d.d,{type:'Snapshot Error',msg:er}); + return; + } + if(d.d.mode==='record'&&s.group[d.d.ke].mon[d.d.id].spawn&&s.group[d.d.ke].mon[d.d.id].spawn.stdin){ + s.group[d.d.ke].mon[d.d.id].spawn.stdin.write(data.body); + } + if(s.group[d.d.ke].mon[d.d.id].watch&&Object.keys(s.group[d.d.ke].mon[d.d.id].watch).length>0){ + s.tx({f:'monitor_frame',ke:d.d.ke,id:d.d.id,time:s.moment(),frame:data.body.toString('base64'),frame_format:'b64'},'MON_'+d.d.id); + } + s.group[d.d.ke].mon[d.d.id].record.capturing=setTimeout(function(){d.d.captureOne()},1000/d.d.details.sfps); + clearTimeout(d.d.timeOut),d.d.timeOut=setTimeout(function(){d.d.error_count=0;},3000) + } + }).on('error', function(err){ +// if(s.group[d.d.ke]&&s.group[d.d.ke].mon[d.d.id]&&s.group[d.d.ke].mon[d.d.id].record&&s.group[d.d.ke].mon[d.d.id].record.request){s.group[d.d.ke].mon[d.d.id].record.request.abort();} + clearTimeout(s.group[d.d.ke].mon[d.d.id].record.capturing); + if(d.d.error_count>4){d.d.fn();return} + d.d.captureOne(); + }); + } + d.d.captureOne() + break; + case'mjpeg':case'h264'://case'socket':case'local': + if(!s.group[d.d.ke]||!s.group[d.d.ke].mon[d.d.id]){s.init(0,d.d)} + if(s.group[d.d.ke].mon[d.d.id].spawn){ + s.group[d.d.ke].mon[d.d.id].spawn.on('error',function(er){d.d.error({type:'Spawn Error',msg:er})}) + s.group[d.d.ke].mon[d.d.id].spawn.stdout.on('data',function(de){ + s.tx({f:'monitor_frame',ke:d.d.ke,id:d.d.id,time:s.moment(),frame:de.toString('base64'),frame_format:'b64'},'MON_'+d.d.id); + }); + s.group[d.d.ke].mon[d.d.id].spawn.stderr.on('data',function(de){ + de=de.toString(); + d.d.chk=function(x){return de.indexOf(x)>-1;} + switch(true){ +// case d.d.chk('av_interleaved_write_frame'): + case d.d.chk('Connection timed out'): + setTimeout(function(){s.log(d.d,{type:"Can't Connect",msg:'Retrying...'});d.d.error_fatal();},1000)//restart + break; + case d.d.chk('No pixel format specified'): + s.log(d.d,{type:"FFMPEG STDERR",msg:{ffmpeg:s.group[d.d.ke].mon[d.d.id].ffmpeg,msg:de}}) + break; + case d.d.chk('RTP: missed'): + case d.d.chk('deprecated pixel format used, make sure you did set range correctly'): + return + break; + case d.d.chk('No such file or directory'): + case d.d.chk('Unable to open RTSP for listening'): + case d.d.chk('timed out'): + case d.d.chk('Invalid data found when processing input'): + case d.d.chk('Immediate exit requested'): + case d.d.chk('reset by peer'): + if(d.d.frames===0&&x==='record'){s.video('delete',d.d)}; + break; + } + s.log(d.d,{type:"FFMPEG STDERR",msg:de}) + }); + } + break; + } + break; + case'video': + s.video(d.d[0],d.d[1]); + break; + } +}); +io.on('disconnect',function(d){ + s.connected=false; +}); + +//web server +if(config.port===undefined)config.port = 8080; +if(config.ip===undefined||config.ip===''||config.ip.indexOf('0.0.0.0')>-1){config.ip='localhost'}else{config.bindip=config.ip}; +var childNodeHTTP = express(); +var childNodeServer = http.createServer(app); +var childNodeWebsocket = new (require('socket.io'))() +childNodeServer.listen(config.port,config.bindip,function(){ + console.log('SHINOBI CHILD NODE RUNNING ON PORT : '+config.port); +}); +childNodeWebsocket.attach(childNodeServer); \ No newline at end of file diff --git a/plugins/child/conf.sample.json b/plugins/child/conf.sample.json new file mode 100644 index 0000000..d1b2008 --- /dev/null +++ b/plugins/child/conf.sample.json @@ -0,0 +1,6 @@ +{ + "name":"childMachine1", + "ws":"192.168.1.48", + "port":8080, + "key":"3123asdasdf1dtj1hjk23sdfaasd12asdasddfdbtnkkfgvesra3asdsd3123afdsfqw345", +} \ No newline at end of file diff --git a/plugins/darknet/INSTALL.sh b/plugins/darknet/INSTALL.sh new file mode 100644 index 0000000..f2cdc4d --- /dev/null +++ b/plugins/darknet/INSTALL.sh @@ -0,0 +1,13 @@ +#!/bin/bash +ln -s /usr/local/cuda/targets/x86_64-linux/lib/libcurand.so /usr/local/lib/libcurand.so +ln -s /usr/local/cuda/targets/x86_64-linux/lib/libcublas.so /usr/local/lib/libcublas.so +ln -s /usr/local/cuda/targets/x86_64-linux/lib/libcudart.so /usr/local/lib/libcudart.so + +git clone https://github.com/OrKoN/darknet +rm darknet/Makefile +cp modifiedMakefile darknet/Makefile +cd darknet +make OPENCV=1 GPU=1 +make install + +npm install @moovel/yolo --unsafe-perm \ No newline at end of file diff --git a/plugins/darknet/conf.sample.json b/plugins/darknet/conf.sample.json new file mode 100644 index 0000000..1a4b8dc --- /dev/null +++ b/plugins/darknet/conf.sample.json @@ -0,0 +1,9 @@ +{ + "plug":"OpenCV", + "host":"localhost", + "port":8080, + "hostPort":8082, + "key":"change_this_to_something_very_random____make_sure_to_match__/plugins/opencv/conf.json", + "mode":"client", + "type":"detector" +} \ No newline at end of file diff --git a/plugins/darknet/modifiedMakefile b/plugins/darknet/modifiedMakefile new file mode 100644 index 0000000..d5f61aa --- /dev/null +++ b/plugins/darknet/modifiedMakefile @@ -0,0 +1,119 @@ +GPU=0 +CUDNN=0 +OPENCV=1 +OPENMP=0 +DEBUG=0 + +PREFIX = /usr/local + +ARCH= #-gencode arch=compute_20,code=[sm_20,sm_21] \ + -gencode arch=compute_30,code=sm_30 \ + -gencode arch=compute_35,code=sm_35 \ + -gencode arch=compute_50,code=[sm_50,compute_50] \ + -gencode arch=compute_52,code=[sm_52,compute_52] + +# This is what I use, uncomment if you know your arch and want to specify +# ARCH= -gencode arch=compute_52,code=compute_52 + +VPATH=./src/:./examples +SLIB=libdarknet.so +ALIB=libdarknet.a +EXEC=darknet +OBJDIR=./obj/ + +CC=gcc +NVCC=nvcc +AR=ar +ARFLAGS=rcs +OPTS=-Ofast +LDFLAGS= -lm -pthread +COMMON= -Iinclude/ -Isrc/ +CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC + +ifeq ($(OPENMP), 1) +CFLAGS+= -fopenmp +endif + +ifeq ($(DEBUG), 1) +OPTS=-O0 -g +endif + +CFLAGS+=$(OPTS) + +ifeq ($(OPENCV), 1) +COMMON+= -DOPENCV +CFLAGS+= -DOPENCV +LDFLAGS+= `pkg-config --libs opencv` +COMMON+= `pkg-config --cflags opencv` +endif + +ifeq ($(GPU), 1) +COMMON+= -DGPU -I/usr/local/cuda/include/ +CFLAGS+= -DGPU +LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand +endif + +ifeq ($(CUDNN), 1) +COMMON+= -DCUDNN +CFLAGS+= -DCUDNN +LDFLAGS+= -lcudnn +endif + +OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o detection_layer.o route_layer.o box.o normalization_layer.o avgpool_layer.o layer.o local_layer.o shortcut_layer.o activation_layer.o rnn_layer.o gru_layer.o crnn_layer.o demo.o batchnorm_layer.o region_layer.o reorg_layer.o tree.o lstm_layer.o +EXECOBJA=captcha.o lsd.o super.o voxel.o art.o tag.o cifar.o go.o rnn.o rnn_vid.o compare.o segmenter.o regressor.o classifier.o coco.o dice.o yolo.o detector.o writing.o nightmare.o swag.o darknet.o +ifeq ($(GPU), 1) +LDFLAGS+= -lstdc++ +OBJ+=convolutional_kernels.o deconvolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o network_kernels.o avgpool_layer_kernels.o +endif + +EXECOBJ = $(addprefix $(OBJDIR), $(EXECOBJA)) +OBJS = $(addprefix $(OBJDIR), $(OBJ)) +DEPS = $(wildcard src/*.h) Makefile include/darknet.h +HEADERS = $(wildcard src/*.h) + +#all: obj backup results $(SLIB) $(ALIB) $(EXEC) +all: obj results $(SLIB) $(ALIB) $(EXEC) + + +$(EXEC): $(EXECOBJ) $(ALIB) + $(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(ALIB) + +$(ALIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $^ + +$(SLIB): $(OBJS) + $(CC) $(CFLAGS) -shared $^ -o $@ $(LDFLAGS) + +$(OBJDIR)%.o: %.c $(DEPS) + $(CC) $(COMMON) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)%.o: %.cu $(DEPS) + $(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $@ + +darknet.a: $(OBJS) + ar rcs $@ $^ + +obj: + mkdir -p obj +backup: + mkdir -p backup +results: + mkdir -p results + +.PHONY: clean + +clean: + rm -rf $(OBJS) $(SLIB) $(ALIB) $(EXEC) $(EXECOBJ) darknet.a + +.PHONY: install + +install: + mkdir -p $(PREFIX)/include/darknet + cp libdarknet.a $(PREFIX)/lib/libdarknet.a + cp ${HEADERS} include/darknet.h $(PREFIX)/include/darknet + +.PHONY: uninstall + +uninstall: + rm -f $(PREFIX)/lib/libdarknet.a + rm -rf $(PREFIX)/include/darknet diff --git a/plugins/darknet/shinobi-darknet.js b/plugins/darknet/shinobi-darknet.js new file mode 100644 index 0000000..85f2470 --- /dev/null +++ b/plugins/darknet/shinobi-darknet.js @@ -0,0 +1,456 @@ +// +// Shinobi - OpenCV Plugin +// Copyright (C) 2016-2025 Moe Alam, moeiscool +// +// # Donate +// +// If you like what I am doing here and want me to continue please consider donating :) +// PayPal : paypal@m03.ca +// +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +var fs=require('fs'); +var cv=require('opencv4nodejs'); +var exec = require('child_process').exec; +var moment = require('moment'); +var Canvas = require('canvas'); +var express = require('express'); +var http = require('http'), + app = express(), + server = http.createServer(app); +var config=require('./conf.json'); +if(!config.port){config.port=8080} +if(!config.hostPort){config.hostPort=8082} +if(config.systemLog===undefined){config.systemLog=true} +if(config.cascadesDir===undefined){config.cascadesDir=__dirname+'/cascades/'} +if(config.alprConfig===undefined){config.alprConfig=__dirname+'/openalpr.conf'} +s={ + group:{}, + dir:{ + cascades : config.cascadesDir + }, + isWin:(process.platform==='win32') +} +//default stream folder check +if(!config.streamDir){ + if(s.isWin===false){ + config.streamDir='/dev/shm' + }else{ + config.streamDir=config.windowsTempDir + } + if(!fs.existsSync(config.streamDir)){ + config.streamDir=__dirname+'/streams/' + }else{ + config.streamDir+='/streams/' + } +} +s.dir.streams=config.streamDir; +//streams dir +if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); +} +s.gid=function(x){ + if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.findCascades=function(callback){ + var tmp={}; + tmp.foundCascades=[]; + fs.readdir(s.dir.cascades,function(err,files){ + files.forEach(function(cascade,n){ + if(cascade.indexOf('.xml')>-1){ + tmp.foundCascades.push(cascade.replace('.xml','')) + } + }) + s.cascadesInDir=tmp.foundCascades; + callback(tmp.foundCascades) + }) +} +s.findCascades(function(){ + //get cascades +}) +s.detectLicensePlate=function(buffer,d,tx){ + if(!d.mon.detector_lisence_plate_country||d.mon.detector_lisence_plate_country===''){ + d.mon.detector_lisence_plate_country='us' + } + d.tmpFile=s.gid(5)+'.jpg' + if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); + } + d.dir=s.dir.streams+d.ke+'/' + if(!fs.existsSync(d.dir)){ + fs.mkdirSync(d.dir); + } + d.dir=s.dir.streams+d.ke+'/'+d.id+'/' + if(!fs.existsSync(d.dir)){ + fs.mkdirSync(d.dir); + } + fs.writeFile(d.dir+d.tmpFile,buffer,function(err){ + if(err) return s.systemLog(err); + exec('alpr -j --config '+config.alprConfig+' -c '+d.mon.detector_lisence_plate_country+' '+d.dir+d.tmpFile,{encoding:'utf8'},(err, scan, stderr) => { + if(err){ + s.systemLog(err); + }else{ + try{ + try{ + scan=JSON.parse(scan.replace('--(!)Loaded CUDA classifier','').trim()) + }catch(err){ + if(!scan||!scan.results){ + return s.systemLog(scan,err); + } + } +// console.log('scan',scan) + if(scan.results.length>0){ + scan.plates=[] + scan.mats=[] + scan.results.forEach(function(v){ + v.candidates.forEach(function(g,n){ + if(v.candidates[n].matches_template) + delete(v.candidates[n].matches_template) + }) + scan.plates.push({coordinates:v.coordinates,candidates:v.candidates,confidence:v.confidence,plate:v.plate}) + var width = Math.sqrt( Math.pow(v.coordinates[1].x - v.coordinates[0].x, 2) + Math.pow(v.coordinates[1].y - v.coordinates[0].y, 2)); + var height = Math.sqrt( Math.pow(v.coordinates[2].x - v.coordinates[1].x, 2) + Math.pow(v.coordinates[2].y - v.coordinates[1].y, 2)) + scan.mats.push({ + x:v.coordinates[0].x, + y:v.coordinates[0].y, + width:width, + height:height, + tag:v.plate + }) + }) + tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:'licensePlate',reason:'object',matrices:scan.mats,imgHeight:d.mon.detector_scale_y,imgWidth:d.mon.detector_scale_x,frame:d.base64}}) + } + }catch(err){ + s.systemLog(scan,err); + } + } + exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'}) + }) + }) +} +s.detectObject=function(buffer,d,tx){ + //detect license plate? + if(d.mon.detector_lisence_plate==="1"){ + s.detectLicensePlate(buffer,d,tx) + } + //check selected opencv cascades + var selectedCascades = Object.keys(d.mon.detector_cascades); + if(selectedCascades.length > 0){ + cv.imdecodeAsync(buffer,(err,im) => { + if(err){ + console.log(err) + return + } + selectedCascades.forEach(function(cascade){ + var classifier = new cv.CascadeClassifier(s.dir.cascades+cascade+'.xml') + var matrices = classifier.detectMultiScaleGpu(im).objects + if(matrices.length > 0){ + matrices.forEach(function(v,n){ + v.centerX=v.width/2 + v.centerY=v.height/2 + v.centerXnoParent=v.x+(v.width/2) + v.centerYnoParent=v.y+(v.height/2) + }) + s.cx({ + f:'trigger', + id:d.id, + ke:d.ke, + name:cascade, + details:{ + plug:'built-in-opencv', + name:cascade, + reason:'object', + matrices : matrices, + confidence:d.average + }, + imgHeight:d.mon.detector_scale_y, + imgWidth:d.mon.detector_scale_x + }) + } + }) + }); + } +} +s.systemLog=function(q,w,e){ + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + return console.log(moment().format(),q,w,e) + } +} + +s.blenderRegion=function(d,cord,tx){ + d.width = d.image.width; + d.height = d.image.height; + if(!s.group[d.ke][d.id].canvas[cord.name]){ + if(!cord.sensitivity||isNaN(cord.sensitivity)){ + cord.sensitivity=d.mon.detector_sensitivity; + } + s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height); + s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d'); + s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#000'; + s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height); + if(cord.points&&cord.points.length>0){ + s.group[d.ke][d.id].canvasContext[cord.name].beginPath(); + for (var b = 0; b < cord.points.length; b++){ + cord.points[b][0]=parseFloat(cord.points[b][0]); + cord.points[b][1]=parseFloat(cord.points[b][1]); + if(b===0){ + s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]); + }else{ + s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]); + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clip(); + } + } + if(!s.group[d.ke][d.id].canvasContext[cord.name]){ + return + } + s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height); + if(!s.group[d.ke][d.id].blendRegion[cord.name]){ + s.group[d.ke][d.id].blendRegion[cord.name] = new Canvas(d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name] = s.group[d.ke][d.id].blendRegion[cord.name].getContext('2d'); + } + var sourceData = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create an image if the previous image doesn�t exist + if (!s.group[d.ke][d.id].lastRegionImageData[cord.name]) s.group[d.ke][d.id].lastRegionImageData[cord.name] = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create a ImageData instance to receive the blended result + var blendedData = s.group[d.ke][d.id].canvasContext[cord.name].createImageData(d.width, d.height); + // blend the 2 images + s.differenceAccuracy(blendedData.data,sourceData.data,s.group[d.ke][d.id].lastRegionImageData[cord.name].data); + // draw the result in a canvas + s.group[d.ke][d.id].blendRegionContext[cord.name].putImageData(blendedData, 0, 0); + // store the current webcam image + s.group[d.ke][d.id].lastRegionImageData[cord.name] = sourceData; + blendedData = s.group[d.ke][d.id].blendRegionContext[cord.name].getImageData(0, 0, d.width, d.height); + var i = 0; + d.average = 0; + while (i < (blendedData.data.length * 0.25)) { + d.average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]); + ++i; + } + d.average = (d.average / (blendedData.data.length * 0.25))*10; + if (d.average > parseFloat(cord.sensitivity)){ + if(d.mon.detector_use_detect_object==="1"&&d.mon.detector_second!=='1'){ + var buffer=s.group[d.ke][d.id].canvas[cord.name].toBuffer(); + s.detectObject(buffer,d,tx) + }else{ + tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:cord.name,reason:'motion',confidence:d.average,frame:d.base64}}) + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name].clearRect(0, 0, d.width, d.height); +} +function blobToBuffer (blob, cb) { + if (typeof Blob === 'undefined' || !(blob instanceof Blob)) { + throw new Error('first argument must be a Blob') + } + if (typeof cb !== 'function') { + throw new Error('second argument must be a function') + } + + var reader = new FileReader() + + function onLoadEnd (e) { + reader.removeEventListener('loadend', onLoadEnd, false) + if (e.error) cb(e.error) + else cb(null, Buffer.from(reader.result)) + } + + reader.addEventListener('loadend', onLoadEnd, false) + reader.readAsArrayBuffer(blob) +} +function fastAbs(value) { + return (value ^ (value >> 31)) - (value >> 31); +} + +function threshold(value) { + return (value > 0x15) ? 0xFF : 0; +} +s.differenceAccuracy=function(target, data1, data2) { + if (data1.length != data2.length) return null; + var i = 0; + while (i < (data1.length * 0.25)) { + var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3; + var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3; + var diff = threshold(fastAbs(average1 - average2)); + target[4 * i] = diff; + target[4 * i + 1] = diff; + target[4 * i + 2] = diff; + target[4 * i + 3] = 0xFF; + ++i; + } +} +s.checkAreas=function(d,tx){ + if(!s.group[d.ke][d.id].cords){ + if(!d.mon.cords){d.mon.cords={}} + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + } + if(d.mon.detector_frame==='1'){ + d.mon.cords.frame={name:'FULL_FRAME',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; + s.group[d.ke][d.id].cords.push(d.mon.cords.frame); + } + for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){ + if(!s.group[d.ke][d.id].cords[b]){return} + s.blenderRegion(d,s.group[d.ke][d.id].cords[b],tx) + } + delete(d.image) +} + +s.MainEventController=function(d,cn,tx){ + switch(d.f){ + case'refreshPlugins': + s.findCascades(function(cascades){ + s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:cascades},to:'GRP_'+d.ke}) + }) + break; + case'readPlugins': + s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:s.cascadesInDir},to:'GRP_'+d.ke}) + break; + case'init_plugin_as_host': + if(!cn){ + console.log('No CN',d) + return + } + if(d.key!==config.key){ + console.log(new Date(),'Plugin Key Mismatch',cn.request.connection.remoteAddress,d) + cn.emit('init',{ok:false}) + cn.disconnect() + }else{ + console.log(new Date(),'Plugin Connected to Client',cn.request.connection.remoteAddress) + cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type}) + } + break; + case'init_monitor': + if(s.group[d.ke]&&s.group[d.ke][d.id]){ + s.group[d.ke][d.id].canvas={} + s.group[d.ke][d.id].canvasContext={} + s.group[d.ke][d.id].blendRegion={} + s.group[d.ke][d.id].blendRegionContext={} + s.group[d.ke][d.id].lastRegionImageData={} + s.group[d.ke][d.id].numberOfTriggers=0 + delete(s.group[d.ke][d.id].cords) + delete(s.group[d.ke][d.id].buffer) + } + break; + case'init_aws_push': +// console.log('init_aws') + s.group[d.ke][d.id].aws={links:[],complete:0,total:d.total,videos:[],tx:tx} + break; + case'frame': + try{ + if(!s.group[d.ke]){ + s.group[d.ke]={} + } + if(!s.group[d.ke][d.id]){ + s.group[d.ke][d.id]={ + canvas:{}, + canvasContext:{}, + lastRegionImageData:{}, + blendRegion:{}, + blendRegionContext:{}, + } + } + if(!s.group[d.ke][d.id].buffer){ + s.group[d.ke][d.id].buffer=[d.frame]; + }else{ + s.group[d.ke][d.id].buffer.push(d.frame) + } + if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ + s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer); + try{ + d.mon.detector_cascades=JSON.parse(d.mon.detector_cascades) + }catch(err){ + + } + if(d.mon.detector_frame_save==="1"){ + d.base64=s.group[d.ke][d.id].buffer.toString('base64') + } + if(d.mon.detector_second==='1'&&d.objectOnly===true){ + s.detectObject(s.group[d.ke][d.id].buffer,d,tx) + }else{ + if((d.mon.detector_pam !== '1' && d.mon.detector_use_motion === "1") || d.mon.detector_use_detect_object !== "1"){ + if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){ + d.mon.cords=[] + }else{ + try{ + d.mon.cords=JSON.parse(d.mon.cords) + }catch(err){ + // console.log('d.mon.cords',err,d) + } + } + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + d.mon.cords=d.mon.cords; + d.image = new Canvas.Image; + if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){ + s.systemLog('Must set detector image size') + return + }else{ + d.image.width=d.mon.detector_scale_x; + d.image.height=d.mon.detector_scale_y; + } + d.width=d.image.width; + d.height=d.image.height; + d.image.onload = function() { + s.checkAreas(d,tx); + } + d.image.src = s.group[d.ke][d.id].buffer; + }else{ + s.detectObject(s.group[d.ke][d.id].buffer,d,tx) + } + } + s.group[d.ke][d.id].buffer=null; + } + }catch(err){ + if(err){ + s.systemLog(err) + delete(s.group[d.ke][d.id].buffer) + } + } + break; + } +} +server.listen(config.hostPort); +//web pages and plugin api +app.get('/', function (req, res) { + res.end(''+config.plug+' for Shinobi is running') +}); +//Conector to Shinobi +if(config.mode==='host'){ + //start plugin as host + var io = require('socket.io')(server); + io.attach(server); + s.connectedClients={}; + io.on('connection', function (cn) { + s.connectedClients[cn.id]={id:cn.id} + s.connectedClients[cn.id].tx = function(data){ + data.pluginKey=config.key;data.plug=config.plug; + return io.to(cn.id).emit('ocv',data); + } + cn.on('f',function(d){ + s.MainEventController(d,cn,s.connectedClients[cn.id].tx) + }); + cn.on('disconnect',function(d){ + delete(s.connectedClients[cn.id]) + }) + }); +}else{ + //start plugin as client + if(!config.host){config.host='localhost'} + var io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master + s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} + io.on('connect',function(d){ + s.cx({f:'init',plug:config.plug,notice:config.notice,type:config.type}); + }) + io.on('disconnect',function(d){ + io.connect(); + }) + io.on('f',function(d){ + s.MainEventController(d,null,s.cx) + }) +} \ No newline at end of file diff --git a/plugins/microsoft/conf.sample.json b/plugins/microsoft/conf.sample.json new file mode 100644 index 0000000..5f9b9dc --- /dev/null +++ b/plugins/microsoft/conf.sample.json @@ -0,0 +1,29 @@ +{ + "plug":"ComputerVision", + "host":"localhost", + "port":8080, + "key":"UNIQUE KEY HERE", + "computerVision":{ + "apiKey":"YOUR_KEY", + "endpoint":"http://YOUR_ENDPOINT/analyze", + "params":{ + "visualFeatures": "Categories,Description,Color", + "details": "", + "language": "en" + } + }, + "EmotionAPI":{ + "apiKey":"YOUR_KEY", + "endpoint":"http://YOUR_ENDPOINT/recognize", + "params":{} + }, + "FaceAPI":{ + "apiKey":"YOUR_KEY", + "endpoint":"http://YOUR_ENDPOINT/detect", + "params":{ + "returnFaceId": "true", + "returnFaceLandmarks": "false", + "returnFaceAttributes": "age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise" + } + } +} \ No newline at end of file diff --git a/plugins/microsoft/shinobi-ms-vision.js b/plugins/microsoft/shinobi-ms-vision.js new file mode 100644 index 0000000..938e787 --- /dev/null +++ b/plugins/microsoft/shinobi-ms-vision.js @@ -0,0 +1,170 @@ +// +// Shinobi - Microsoft Computer Vision Plugin +// Copyright (C) 2016-2025 Moe Alam, moeiscool +// +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +var fs=require('fs'); +var exec = require('child_process').exec; +//var http = require('http'); +var request = require('request'); +var moment = require('moment'); +var cognitive = require('cognitive-services'); +var config=require('./conf.json'); +if(config.systemLog===undefined){config.systemLog=true} +s={ + group:{}, + dir:{ + cascades:__dirname+'/cascades/' + }, + isWin:(process.platform==='win32') +} +//default stream folder check +if(!config.streamDir){ + if(s.isWin===false){ + config.streamDir='/dev/shm' + }else{ + config.streamDir=config.windowsTempDir + } + if(!fs.existsSync(config.streamDir)){ + config.streamDir=__dirname+'/streams/' + }else{ + config.streamDir+='/streams/' + } +} +s.dir.streams=config.streamDir; +//streams dir +if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); +} +s.gid=function(x){ + if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.systemLog=function(q,w,e){ + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + return console.log(moment().format(),q,w,e) + } +} +s.objectToParameter = function(obj){ + return Object.keys(obj).map(function(key) { + return key + '=' + encodeURIComponent(obj[key]); + }).join('&'); +} +s.sendImageToMS=function(sourceImageUrl,API,callback){ + var URL = API.endpoint+'?'+s.objectToParameter(API.params) + request(URL,{ + method: 'POST', + headers:{ + "Ocp-Apim-Subscription-Key":API.apiKey + }, + json: { + url:sourceImageUrl + } + }, callback) +} +s.detectObject=function(buffer,d){ + var sourceImageUrl = 'http://184.105.6.43/'+s.api_key+'/jpeg/'+d.ke+'/'+d.id+'/s.jpg' +// const client = new cognitive.computerVision({ +// apiKey: config.computerVision.apiKey, +// endpoint: config.computerVision.endpoint +// }); +// const parameters = { +// "visualFeatures": "Categories,Tags,Description", +// "details": "Celebrities,Landmarks" +// }; +// const headers = { +// 'Content-type': 'application/json' +// }; +// const body = { +// "url": sourceImageUrl +// }; +// +// client.analyzeImage({ +// parameters, +// headers, +// body +// }).then((response) => { +//// should(response).not.be.undefined(); +//// should(response).have.properties(["categories", "metadata", "requestId"]); +// console.log(response) +// }).catch((err) => { +// console.log('Error',err) +// }); + var responses = {} + s.sendImageToMS(sourceImageUrl,config.computerVision,function(err,resp,body1){ + responses.computerVisionURL = body1 + s.sendImageToMS(sourceImageUrl,config.FaceAPI,function(err,resp,body2){ + responses.faceApiURL = body2 + s.sendImageToMS(sourceImageUrl,config.EmotionAPI,function(err,resp,body3){ + responses.EmotionAPI = body3 + console.log('responses',JSON.stringify(responses,null,3)) + }) + }) + }) +} +s.makeMonitorObject=function(d){ + if(!s.group[d.ke]){ + s.group[d.ke]={} + } + if(!s.group[d.ke][d.id]){ + s.group[d.ke][d.id]={ + port:null, + countStarted:new Date() + } + } +} +io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master +s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} +io.on('connect',function(d){ + s.cx({f:'init',plug:config.plug}); +}) +io.on('disconnect',function(d){ + io.connect() +}) +io.on('f',function(d){ + switch(d.f){ + case'api_key': + s.api_key=d.key + break; + case'init_monitor': + if(s.group[d.ke]&&s.group[d.ke][d.id]){ + s.group[d.ke][d.id].buffer=null + s.group[d.ke][d.id].countStarted=new Date() + } + s.makeMonitorObject(d) + break; + case'frame': + d.details={} + try{ + s.makeMonitorObject(d) + if(!s.group[d.ke][d.id].buffer){ + s.group[d.ke][d.id].buffer=[d.frame]; + }else{ + s.group[d.ke][d.id].buffer.push(d.frame) + } + if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ + if(d.mon.detector_frame_save==="1"){ + d.base64=s.group[d.ke][d.id].buffer.toString('base64') + } + if(d.mon.detector_scale_x&&d.mon.detector_scale_x!==''&&d.mon.detector_scale_y&&d.mon.detector_scale_y!==''){ + d.width=d.mon.detector_scale_x; + d.height=d.mon.detector_scale_y; + }else{ + d.width=640 + d.height=480 + } + s.detectObject(Buffer.concat(s.group[d.ke][d.id].buffer),d) + s.group[d.ke][d.id].buffer=null; + } + } catch(err){ + console.error(err) + } + break; + } +}) \ No newline at end of file diff --git a/plugins/motion/.gitignore b/plugins/motion/.gitignore new file mode 100644 index 0000000..85825a5 --- /dev/null +++ b/plugins/motion/.gitignore @@ -0,0 +1 @@ +conf.json diff --git a/plugins/motion/INSTALL.sh b/plugins/motion/INSTALL.sh new file mode 100644 index 0000000..902d6ab --- /dev/null +++ b/plugins/motion/INSTALL.sh @@ -0,0 +1,5 @@ +apt-get install libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev build-essential g++ +npm install canvas +cd plugins/motion +cp conf.sample.json conf.json +pm2 start shinobi-motion.js \ No newline at end of file diff --git a/plugins/motion/README.md b/plugins/motion/README.md new file mode 100644 index 0000000..ca3c6f4 --- /dev/null +++ b/plugins/motion/README.md @@ -0,0 +1,56 @@ +# Shinobi Motion Detector + +Install required libraries. + +**Ubuntu and Debian only** + +``` +sudo apt-get install libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev build-essential g++ +``` + +**CentOS only** + +``` +su -c 'yum install cairo cairo-devel cairomm-devel libjpeg-turbo-devel pango pango-devel pangomm pangomm-devel giflib-devel' +yum search arial +yum install liberation-sans-fonts.noarch +``` + +**Install the Node.js Canvas engine** + +``` +sudo npm install canvas +``` + +Go to the Shinobi directory. **Below is an example.** + +``` +cd /home/Shinobi +``` + +Copy the config file. + +``` +cp plugins/motion/conf.sample.json plugins/motion/conf.json +``` + +Edit it the new file. Host should be `localhost` and port should match the `listening port for camera.js`. + +``` +nano plugins/motion/conf.json +``` + +Start the plugin. + +``` +node plugins/motion/shinobi-motion.js +``` + +Or to daemonize with PM2. + +``` +pm2 start plugins/motion/shinobi-motion.js +``` + +Doing this will reveal options in the monitor configuration. Shinobi does not need to be restarted when a plugin is initiated or stopped. + diff --git a/plugins/motion/conf.sample.json b/plugins/motion/conf.sample.json new file mode 100644 index 0000000..171a562 --- /dev/null +++ b/plugins/motion/conf.sample.json @@ -0,0 +1,7 @@ +{ + "plug":"Motion", + "host":"localhost", + "port":8080, + "key":"change_this_to_something_very_random____make_sure_to_match__/plugins/motion/conf.json", + "notice":"Looks like you have the Motion plugin running. Don't forget to enable Send Frames to start pushing frames to be read." +} \ No newline at end of file diff --git a/plugins/motion/libs/clusterPoints.js b/plugins/motion/libs/clusterPoints.js new file mode 100644 index 0000000..9d05fe8 --- /dev/null +++ b/plugins/motion/libs/clusterPoints.js @@ -0,0 +1,115 @@ +'use strict' + +module.exports = { + + data: getterSetter([], function(arrayOfArrays) { + var n = arrayOfArrays[0].length; + return (arrayOfArrays.map(function(array) { + return array.length == n; + }).reduce(function(boolA, boolB) { return (boolA & boolB) }, true)); + }), + + clusters: function() { + var pointsAndCentroids = kmeans(this.data(), {k: this.k(), iterations: this.iterations() }); + var points = pointsAndCentroids.points; + var centroids = pointsAndCentroids.centroids; + + return centroids.map(function(centroid) { + return { + centroid: centroid.location(), + points: points.filter(function(point) { return point.label() == centroid.label() }).map(function(point) { return point.location() }), + }; + }); + }, + + k: getterSetter(undefined, function(value) { return ((value % 1 == 0) & (value > 0)) }), + + iterations: getterSetter(Math.pow(10, 3), function(value) { return ((value % 1 == 0) & (value > 0)) }), + +}; + +function kmeans(data, config) { + // default k + var k = config.k || Math.round(Math.sqrt(data.length / 2)); + var iterations = config.iterations; + + // initialize point objects with data + var points = data.map(function(vector) { return new Point(vector) }); + + // intialize centroids randomly + var centroids = []; + for (var i = 0; i < k; i++) { + centroids.push(new Centroid(points[i % points.length].location(), i)); + }; + + // update labels and centroid locations until convergence + for (var iter = 0; iter < iterations; iter++) { + points.forEach(function(point) { point.updateLabel(centroids) }); + centroids.forEach(function(centroid) { centroid.updateLocation(points) }); + }; + + // return points and centroids + return { + points: points, + centroids: centroids + }; + +}; + +// objects +function Point(location) { + var self = this; + this.location = getterSetter(location); + this.label = getterSetter(); + this.updateLabel = function(centroids) { + var distancesSquared = centroids.map(function(centroid) { + return sumOfSquareDiffs(self.location(), centroid.location()); + }); + self.label(mindex(distancesSquared)); + }; +}; + +function Centroid(initialLocation, label) { + var self = this; + this.location = getterSetter(initialLocation); + this.label = getterSetter(label); + this.updateLocation = function(points) { + var pointsWithThisCentroid = points.filter(function(point) { return point.label() == self.label() }); + if (pointsWithThisCentroid.length > 0) self.location(averageLocation(pointsWithThisCentroid)); + }; +}; + +// convenience functions +function getterSetter(initialValue, validator) { + var thingToGetSet = initialValue; + var isValid = validator || function(val) { return true }; + return function(newValue) { + if (typeof newValue === 'undefined') return thingToGetSet; + if (isValid(newValue)) thingToGetSet = newValue; + }; +}; + +function sumOfSquareDiffs(oneVector, anotherVector) { + var squareDiffs = oneVector.map(function(component, i) { + return Math.pow(component - anotherVector[i], 2); + }); + return squareDiffs.reduce(function(a, b) { return a + b }, 0); +}; + +function mindex(array) { + var min = array.reduce(function(a, b) { + return Math.min(a, b); + }); + return array.indexOf(min); +}; + +function sumVectors(a, b) { + return a.map(function(val, i) { return val + b[i] }); +}; + +function averageLocation(points) { + var zeroVector = points[0].location().map(function() { return 0 }); + var locations = points.map(function(point) { return point.location() }); + var vectorSum = locations.reduce(function(a, b) { return sumVectors(a, b) }, zeroVector); + return vectorSum.map(function(val) { return val / points.length }); +}; diff --git a/plugins/motion/shinobi-motion-pixel.js b/plugins/motion/shinobi-motion-pixel.js new file mode 100644 index 0000000..6dfba78 --- /dev/null +++ b/plugins/motion/shinobi-motion-pixel.js @@ -0,0 +1,245 @@ +// +// Shinobi - Motion Plugin +// Copyright (C) 2016-2025 Moe Alam, moeiscool +// +// # Donate +// +// If you like what I am doing here and want me to continue please consider donating :) +// PayPal : paypal@m03.ca +// +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +var fs = require('fs'); +var moment = require('moment'); +var Canvas = require('canvas'); +var Cluster = require('./libs/clusterPoints.js'); +var config=require('./conf.json'); +if(process.argv[2]&&process.argv[3]){ + config.host=process.argv[2] + config.port=process.argv[3] + config.key=process.argv[4] +} +if(config.systemLog===undefined){config.systemLog=true} +s={ + group:{}, +} +s.systemLog=function(q,w,e){ + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + return console.log(moment().format(),q,w,e) + } +} +s.checkRegion=function(d,cord){ + d.width = d.image.width; + d.height = d.image.height; + if(!s.group[d.ke][d.id].canvas[cord.name]){ + if(!cord.sensitivity||isNaN(cord.sensitivity)){ + cord.sensitivity=d.mon.detector_sensitivity; + } + s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height); + s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d'); + s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#005337'; + s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height); + if(cord.points&&cord.points.length>0){ + s.group[d.ke][d.id].canvasContext[cord.name].beginPath(); + for (var b = 0; b < cord.points.length; b++){ + cord.points[b][0]=parseFloat(cord.points[b][0]); + cord.points[b][1]=parseFloat(cord.points[b][1]); + if(b===0){ + s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]); + }else{ + s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]); + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clip(); + } + } + s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height); + var blenderCanvas = s.group[d.ke][d.id].canvas[cord.name]; + var blenderCanvasContext = s.group[d.ke][d.id].canvasContext[cord.name]; + s.group[d.ke][d.id].frameSelected[s.group[d.ke][d.id].frameNumber] = blenderCanvasContext.getImageData(0, 0, blenderCanvas.width, blenderCanvas.height); + s.group[d.ke][d.id].frameNumber = 0 == s.group[d.ke][d.id].frameNumber ? 1 : 0; + s.group[d.ke][d.id].lastRegionImageData = blenderCanvasContext.getImageData(0, 0, blenderCanvas.width, blenderCanvas.height); + if(!s.group[d.ke][d.id].lastRegionImageData){return} + var foundPixels = []; + var average = 0; + var currentImageLength = s.group[d.ke][d.id].lastRegionImageData.data.length * 0.25; + for (b = 0; b < currentImageLength;){ + var pos = b * 4 + s.group[d.ke][d.id].lastRegionImageData.data[pos] = .5 * (255 - s.group[d.ke][d.id].lastRegionImageData.data[pos]) + .5 * s.group[d.ke][d.id].frameSelected[s.group[d.ke][d.id].frameNumber].data[pos]; + s.group[d.ke][d.id].lastRegionImageData.data[pos + 1] = .5 * (255 - s.group[d.ke][d.id].lastRegionImageData.data[pos + 1]) + .5 * s.group[d.ke][d.id].frameSelected[s.group[d.ke][d.id].frameNumber].data[pos + 1]; + s.group[d.ke][d.id].lastRegionImageData.data[pos + 2] = .5 * (255 - s.group[d.ke][d.id].lastRegionImageData.data[pos + 2]) + .5 * s.group[d.ke][d.id].frameSelected[s.group[d.ke][d.id].frameNumber].data[pos + 2]; + s.group[d.ke][d.id].lastRegionImageData.data[pos + 3] = 255; + var score = (s.group[d.ke][d.id].lastRegionImageData.data[pos] + s.group[d.ke][d.id].lastRegionImageData.data[pos + 1] + s.group[d.ke][d.id].lastRegionImageData.data[pos + 2]) / 3; + if(score>170){ + var x = (pos / 4) % d.width; + var y = Math.floor((pos / 4) / d.width); + foundPixels.push([x,y]) + } + + average += (s.group[d.ke][d.id].lastRegionImageData.data[b * 4] + s.group[d.ke][d.id].lastRegionImageData.data[b * 4 + 1] + s.group[d.ke][d.id].lastRegionImageData.data[b * 4 + 2]); + + b += 4; + } +// console.log(foundPixels) + var matrices + if(d.mon.detector_region_of_interest==='1'&&foundPixels.length>0){ + var groupedPoints = Object.assign({},Cluster); + groupedPoints.iterations(25); + groupedPoints.data(foundPixels); + var groupedPoints = groupedPoints.clusters() + var matrices=[] + var mostHeight = 0; + var mostWidth = 0; + var mostWithMotion = null; + groupedPoints.forEach(function(v,n){ + var matrix = { + topLeft:[d.width,d.height], + topRight:[0,d.height], + bottomRight:[0,0], + bottomLeft:[d.width,0], + } + v.points.forEach(function(b){ + var x = b[0] + var y = b[1] + if(xmatrix.topRight[0])matrix.topRight[0]=x; + if(ymatrix.bottomRight[0])matrix.bottomRight[0]=x; + if(y>matrix.bottomRight[1])matrix.bottomRight[1]=y; + //Bottom Left point + if(xmatrix.bottomLeft[1])matrix.bottomLeft[1]=y; + }) + matrix.x = matrix.topLeft[0]; + matrix.y = matrix.topLeft[1]; + matrix.width = matrix.topRight[0] - matrix.topLeft[0] + matrix.height = matrix.bottomLeft[1] - matrix.topLeft[1] + + if(matrix.width>mostWidth&&matrix.height>mostHeight){ + mostWidth = matrix.width; + mostHeight = matrix.height; + mostWithMotion = matrix; + } + + matrices.push(matrix) + }) + } + average = (average / (currentImageLength)); + if (average > parseFloat(cord.sensitivity)){ + s.cx({f:'trigger',id:d.id,ke:d.ke,details:{plug:config.plug,name:cord.name,reason:'motion',confidence:average,matrices:matrices}}) + } + s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height); +} +s.checkAreas=function(d){ + if(!s.group[d.ke][d.id].cords){ + if(!d.mon.cords){d.mon.cords={}} + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + } + if(d.mon.detector_frame==='1'){ + d.mon.cords.frame={name:'frame',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; + s.group[d.ke][d.id].cords.push(d.mon.cords.frame); + } + for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){ + if(!s.group[d.ke][d.id].cords[b]){return} + s.checkRegion(d,s.group[d.ke][d.id].cords[b]) + } + delete(d.image) +} + +io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master +s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} +io.on('connect',function(d){ + s.cx({f:'init',plug:config.plug,notice:config.notice}); +}) +io.on('disconnect',function(d){ + io.connect(); +}) +io.on('f',function(d){ + switch(d.f){ + case'init_monitor': + if(s.group[d.ke]&&s.group[d.ke][d.id]){ + s.group[d.ke][d.id].canvas={} + s.group[d.ke][d.id].canvasContext={} + s.group[d.ke][d.id].lastRegionImageData=undefined + s.group[d.ke][d.id].frameNumber=0 + s.group[d.ke][d.id].frameSelected=[] + delete(s.group[d.ke][d.id].cords) + delete(s.group[d.ke][d.id].buffer) + } + break; + case'frame': + try{ + if(!s.group[d.ke]){ + s.group[d.ke]={} + } + if(!s.group[d.ke][d.id]){ + s.group[d.ke][d.id]={ + canvas:{}, + canvasContext:{}, + lastRegionImageData:undefined, + frameNumber:0, + frameSelected:[], + } + } + if(!s.group[d.ke][d.id].buffer){ + s.group[d.ke][d.id].buffer=[d.frame]; + }else{ + s.group[d.ke][d.id].buffer.push(d.frame) + } + if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ + if(s.group[d.ke][d.id].motion_lock){ + return + }else{ + if(!d.mon.detector_lock_timeout||d.mon.detector_lock_timeout===''||d.mon.detector_lock_timeout==0){ + d.mon.detector_lock_timeout=2000 + }else{ + d.mon.detector_lock_timeout=parseFloat(d.mon.detector_lock_timeout) + } + s.group[d.ke][d.id].motion_lock=setTimeout(function(){ + clearTimeout(s.group[d.ke][d.id].motion_lock); + delete(s.group[d.ke][d.id].motion_lock); + },d.mon.detector_lock_timeout) + } + s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer); + if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){ + d.mon.cords=[] + }else{ + try{ + d.mon.cords=JSON.parse(d.mon.cords) + }catch(err){ + } + } + if(d.mon.detector_frame_save==="1"){ + d.base64=s.group[d.ke][d.id].buffer.toString('base64') + } + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + d.mon.cords=d.mon.cords; + d.image = new Canvas.Image; + if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){ + s.systemLog('Must set detector image size') + return + }else{ + d.image.width=d.mon.detector_scale_x; + d.image.height=d.mon.detector_scale_y; + } + d.image.onload = function() { + s.checkAreas(d); + } + d.image.src = s.group[d.ke][d.id].buffer; + s.group[d.ke][d.id].buffer=null; + } + }catch(err){ + if(err){ + s.systemLog(err) + delete(s.group[d.ke][d.id].buffer) + } + } + break; + } +}) \ No newline at end of file diff --git a/plugins/motion/shinobi-motion.js b/plugins/motion/shinobi-motion.js new file mode 100644 index 0000000..3b003cf --- /dev/null +++ b/plugins/motion/shinobi-motion.js @@ -0,0 +1,233 @@ +// +// Shinobi - Motion Plugin +// Copyright (C) 2016-2025 Moe Alam, moeiscool +// +// # Donate +// +// If you like what I am doing here and want me to continue please consider donating :) +// PayPal : paypal@m03.ca +// +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +var fs = require('fs'); +var moment = require('moment'); +var Canvas = require('canvas'); +var config=require('./conf.json'); +if(process.argv[2]&&process.argv[3]){ + config.host=process.argv[2] + config.port=process.argv[3] + config.key=process.argv[4] +} +if(config.systemLog===undefined){config.systemLog=true} +s={ + group:{}, +} +s.systemLog=function(q,w,e){ + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + return console.log(moment().format(),q,w,e) + } +} +s.blenderRegion=function(d,cord){ + d.width = d.image.width; + d.height = d.image.height; + if(!s.group[d.ke][d.id].canvas[cord.name]){ + if(!cord.sensitivity||isNaN(cord.sensitivity)){ + cord.sensitivity=d.mon.detector_sensitivity; + } + s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height); + s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d'); + s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#005337'; + s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height); + if(cord.points&&cord.points.length>0){ + s.group[d.ke][d.id].canvasContext[cord.name].beginPath(); + for (var b = 0; b < cord.points.length; b++){ + cord.points[b][0]=parseFloat(cord.points[b][0]); + cord.points[b][1]=parseFloat(cord.points[b][1]); + if(b===0){ + s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]); + }else{ + s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]); + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clip(); + } + } + if(!s.group[d.ke][d.id].canvasContext[cord.name]){ + return + } + s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height); + if(!s.group[d.ke][d.id].blendRegion[cord.name]){ + s.group[d.ke][d.id].blendRegion[cord.name] = new Canvas(d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name] = s.group[d.ke][d.id].blendRegion[cord.name].getContext('2d'); + } + var sourceData = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create an image if the previous image doesn�t exist + if (!s.group[d.ke][d.id].lastRegionImageData[cord.name]) s.group[d.ke][d.id].lastRegionImageData[cord.name] = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create a ImageData instance to receive the blended result + var blendedData = s.group[d.ke][d.id].canvasContext[cord.name].createImageData(d.width, d.height); + // blend the 2 images + s.differenceAccuracy(blendedData.data,sourceData.data,s.group[d.ke][d.id].lastRegionImageData[cord.name].data); + // draw the result in a canvas + s.group[d.ke][d.id].blendRegionContext[cord.name].putImageData(blendedData, 0, 0); + // store the current webcam image + s.group[d.ke][d.id].lastRegionImageData[cord.name] = sourceData; + blendedData = s.group[d.ke][d.id].blendRegionContext[cord.name].getImageData(0, 0, d.width, d.height); + var i = 0; + var average = 0; + while (i < (blendedData.data.length * 0.25)) { + average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]); + ++i; + } + average = (average / (blendedData.data.length * 0.25))*10; + if (average > parseFloat(cord.sensitivity)){ + s.cx({f:'trigger',id:d.id,ke:d.ke,details:{plug:config.plug,name:cord.name,reason:'motion',confidence:average}}) + + } + s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name].clearRect(0, 0, d.width, d.height); +} +function fastAbs(value) { + return (value ^ (value >> 31)) - (value >> 31); +} + +function threshold(value) { + return (value > 0x15) ? 0xFF : 0; +} + +function difference(target, data1, data2) { + // blend mode difference + if (data1.length != data2.length) return null; + var i = 0; + while (i < (data1.length * 0.25)) { + target[4 * i] = data1[4 * i] == 0 ? 0 : fastAbs(data1[4 * i] - data2[4 * i]); + target[4 * i + 1] = data1[4 * i + 1] == 0 ? 0 : fastAbs(data1[4 * i + 1] - data2[4 * i + 1]); + target[4 * i + 2] = data1[4 * i + 2] == 0 ? 0 : fastAbs(data1[4 * i + 2] - data2[4 * i + 2]); + target[4 * i + 3] = 0xFF; + ++i; + } +} +s.differenceAccuracy=function(target, data1, data2) { + if (data1.length != data2.length) return null; + var i = 0; + while (i < (data1.length * 0.25)) { + var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3; + var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3; + var diff = threshold(fastAbs(average1 - average2)); + target[4 * i] = diff; + target[4 * i + 1] = diff; + target[4 * i + 2] = diff; + target[4 * i + 3] = 0xFF; + ++i; + } +} + +s.checkAreas=function(d){ + if(!s.group[d.ke][d.id].cords){ + if(!d.mon.cords){d.mon.cords={}} + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + } + if(d.mon.detector_frame==='1'){ + d.mon.cords.frame={name:'frame',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; + s.group[d.ke][d.id].cords.push(d.mon.cords.frame); + } + for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){ + if(!s.group[d.ke][d.id].cords[b]){return} + s.blenderRegion(d,s.group[d.ke][d.id].cords[b]) + } + delete(d.image) +} + +io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master +s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} +io.on('connect',function(d){ + s.cx({f:'init',plug:config.plug,notice:config.notice}); +}) +io.on('disconnect',function(d){ + io.connect(); +}) +io.on('f',function(d){ + switch(d.f){ + case'init_monitor': + if(s.group[d.ke]&&s.group[d.ke][d.id]){ + s.group[d.ke][d.id].canvas={} + s.group[d.ke][d.id].canvasContext={} + s.group[d.ke][d.id].blendRegion={} + s.group[d.ke][d.id].blendRegionContext={} + s.group[d.ke][d.id].lastRegionImageData={} + delete(s.group[d.ke][d.id].cords) + delete(s.group[d.ke][d.id].buffer) + } + break; + case'frame': + try{ + if(!s.group[d.ke]){ + s.group[d.ke]={} + } + if(!s.group[d.ke][d.id]){ + s.group[d.ke][d.id]={ + canvas:{}, + canvasContext:{}, + lastRegionImageData:{}, + blendRegion:{}, + blendRegionContext:{}, + } + } + if(!s.group[d.ke][d.id].buffer){ + s.group[d.ke][d.id].buffer=[d.frame]; + }else{ + s.group[d.ke][d.id].buffer.push(d.frame) + } + if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ + if(s.group[d.ke][d.id].motion_lock){ + return + }else{ + if(!d.mon.detector_lock_timeout||d.mon.detector_lock_timeout===''||d.mon.detector_lock_timeout==0){ + d.mon.detector_lock_timeout=2000 + }else{ + d.mon.detector_lock_timeout=parseFloat(d.mon.detector_lock_timeout) + } + s.group[d.ke][d.id].motion_lock=setTimeout(function(){ + clearTimeout(s.group[d.ke][d.id].motion_lock); + delete(s.group[d.ke][d.id].motion_lock); + },d.mon.detector_lock_timeout) + } + s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer); + if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){ + d.mon.cords=[] + }else{ + try{ + d.mon.cords=JSON.parse(d.mon.cords) + }catch(err){ + } + } + if(d.mon.detector_frame_save==="1"){ + d.base64=s.group[d.ke][d.id].buffer.toString('base64') + } + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + d.mon.cords=d.mon.cords; + d.image = new Canvas.Image; + if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){ + s.systemLog('Must set detector image size') + return + }else{ + d.image.width=d.mon.detector_scale_x; + d.image.height=d.mon.detector_scale_y; + } + d.image.onload = function() { + s.checkAreas(d); + } + d.image.src = s.group[d.ke][d.id].buffer; + s.group[d.ke][d.id].buffer=null; + } + }catch(err){ + if(err){ + s.systemLog(err) + delete(s.group[d.ke][d.id].buffer) + } + } + break; + } +}) \ No newline at end of file diff --git a/plugins/openalpr/.gitignore b/plugins/openalpr/.gitignore new file mode 100644 index 0000000..5881654 --- /dev/null +++ b/plugins/openalpr/.gitignore @@ -0,0 +1,2 @@ +conf.json +cascades \ No newline at end of file diff --git a/plugins/openalpr/README.md b/plugins/openalpr/README.md new file mode 100644 index 0000000..36a023f --- /dev/null +++ b/plugins/openalpr/README.md @@ -0,0 +1,93 @@ +# OpenALPR and Motion Detector + +Install required libraries. + +**Ubuntu and Debian only** + +``` +sudo apt update && sudo apt install libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev build-essential g++ openalpr openalpr-daemon openalpr-utils libopenalpr-dev -y +``` + +**Install the Node.js Canvas engine** + +``` +sudo npm install canvas@1.6 +``` +Go to the Shinobi directory. **Below is an example.** + +``` +cd /home/Shinobi +``` + +Copy the config file. + +``` +cp plugins/openalpr/conf.sample.json plugins/openalpr/conf.json +``` + +Edit it the new file. Host should be `localhost` and port should match the `listening port for camera.js`. + +``` +nano plugins/openalpr/conf.json +``` + +Start the plugin. + +``` +node plugins/openalpr/shinobi-motion.js +``` + +Or to daemonize with PM2. + +``` +pm2 start plugins/openalpr/shinobi-motion.js +``` + +Doing this will reveal options in the monitor configuration. Shinobi does not need to be restarted when a plugin is initiated or stopped. + +## Run the plugin as a Host +> The main app (Shinobi) will be the client and the plugin will be the host. The purpose of allowing this method is so that you can use one plugin for multiple Shinobi instances. Allowing you to easily manage connections without starting multiple processes. + +Edit your plugins configuration file. Set the `hostPort` **to be different** than the `listening port for camera.js`. + +``` +nano plugins/openalpr/conf.json +``` + +Here is a sample of a Host configuration for the plugin. + - `plug` is the name of the plugin corresponding in the main configuration file. + - `https` choose if you want to use SSL or not. Default is `false`. + - `hostPort` can be any available port number. **Don't make this the same port number as Shinobi.** Default is `8082`. + - `type` tells the main application (Shinobi) what kind of plugin it is. In this case it is a detector. + +``` +{ + "plug":"OpenALPR", + "hostPort":8082, + "key":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi", + "mode":"host", + "type":"detector" +} +``` + +Now modify the **main configuration file** located in the main directory of Shinobi. *Where you currently should be.* + +``` +nano conf.json +``` + +Add the `plugins` array if you don't already have it. Add the following *object inside the array*. + +``` + "plugins":[ + { + "id" : "OpenALPR", + "https" : false, + "host" : "localhost", + "port" : 8082, + "key" : "SomeOpenALPRkeySoPeopleDontMessWithYourShinobi", + "mode" : "host", + "type" : "detector" + } + ], +``` \ No newline at end of file diff --git a/plugins/openalpr/conf.sample.json b/plugins/openalpr/conf.sample.json new file mode 100644 index 0000000..08ce79d --- /dev/null +++ b/plugins/openalpr/conf.sample.json @@ -0,0 +1,9 @@ +{ + "plug":"OpenALPR", + "host":"localhost", + "port":8080, + "hostPort":8082, + "key":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi", + "mode":"client", + "type":"detector" +} \ No newline at end of file diff --git a/plugins/openalpr/openalpr.conf b/plugins/openalpr/openalpr.conf new file mode 100644 index 0000000..070752b --- /dev/null +++ b/plugins/openalpr/openalpr.conf @@ -0,0 +1,94 @@ + +; Specify the path to the runtime data directory +runtime_dir = ${CMAKE_INSTALL_PREFIX}/share/openalpr/runtime_data + + +ocr_img_size_percent = 1.33333333 +state_id_img_size_percent = 2.0 + +; Calibrating your camera improves detection accuracy in cases where vehicle plates are captured at a steep angle +; Use the openalpr-utils-calibrate utility to calibrate your fixed camera to adjust for an angle +; Once done, update the prewarp config with the values obtained from the tool +prewarp = + +; detection will ignore plates that are too large. This is a good efficiency technique to use if the +; plates are going to be a fixed distance away from the camera (e.g., you will never see plates that fill +; up the entire image +max_plate_width_percent = 100 +max_plate_height_percent = 100 + +; detection_iteration_increase is the percentage that the LBP frame increases each iteration. +; It must be greater than 1.0. A value of 1.01 means increase by 1%, 1.10 increases it by 10% each time. +; So a 1% increase would be ~10x slower than 10% to process, but it has a higher chance of landing +; directly on the plate and getting a strong detection +detection_iteration_increase = 1.1 + +; The minimum detection strength determines how sure the detection algorithm must be before signaling that +; a plate region exists. Technically this corresponds to LBP nearest neighbors (e.g., how many detections +; are clustered around the same area). For example, 2 = very lenient, 9 = very strict. +detection_strictness = 3 + +; The detection doesn't necessarily need an extremely high resolution image in order to detect plates +; Using a smaller input image should still find the plates and will do it faster +; Tweaking the max_detection_input values will resize the input image if it is larger than these sizes +; max_detection_input_width/height are specified in pixels +max_detection_input_width = 1280 +max_detection_input_height = 720 + +; detector is the technique used to find license plate regions in an image. Value can be set to +; lbpcpu - default LBP-based detector uses the system CPU +; lbpgpu - LBP-based detector that uses Nvidia GPU to increase recognition speed. +; lbpopencl - LBP-based detector that uses OpenCL GPU to increase recognition speed. Requires OpenCV 3.0 +; morphcpu - Experimental detector that detects white rectangles in an image. Does not require training. +detector = lbpgpu + +; If set to true, all results must match a postprocess text pattern if a pattern is available. +; If not, the result is disqualified. +must_match_pattern = 0 + +; Bypasses plate detection. If this is set to 1, the library assumes that each region provided is a likely plate area. +skip_detection = 0 + +; Specifies the full path to an image file that constrains the detection area. Only the plate regions allowed through the mask +; will be analyzed. The mask image must match the resolution of your image to be analyzed. The mask is black and white. +; Black areas will be ignored, white areas will be searched. An empty value means no mask (scan the entire image) +detection_mask_image = + +; OpenALPR can scan the same image multiple times with different randomization. Setting this to a value larger than +; 1 may increase accuracy, but will increase processing time linearly (e.g., analysis_count = 3 is 3x slower) +analysis_count = 1 + +; OpenALPR detects high-contrast plate crops and uses an alternative edge detection technique. Setting this to 0.0 +; would classify ALL images as high-contrast, setting it to 1.0 would classify no images as high-contrast. +contrast_detection_threshold = 0.3 + +max_plate_angle_degrees = 15 + +ocr_min_font_point = 6 + +; Minimum OCR confidence percent to consider. +postprocess_min_confidence = 65 + +; Any OCR character lower than this will also add an equally likely +; chance that the character is incorrect and will be skipped. Value is a confidence percent +postprocess_confidence_skip_level = 80 + + +debug_general = 0 +debug_timing = 0 +debug_detector = 0 +debug_prewarp = 0 +debug_state_id = 0 +debug_plate_lines = 0 +debug_plate_corners = 0 +debug_char_segment = 0 +debug_char_analysis = 0 +debug_color_filter = 0 +debug_ocr = 0 +debug_postprocess = 0 +debug_show_images = 0 +debug_pause_on_frame = 0 + + + + diff --git a/plugins/openalpr/package.json b/plugins/openalpr/package.json new file mode 100644 index 0000000..7f6d5aa --- /dev/null +++ b/plugins/openalpr/package.json @@ -0,0 +1,18 @@ +{ + "name": "shinobi-openalpr", + "version": "1.0.0", + "description": "OpenALPR plugin for Shinobi", + "main": "shinobi-openalpr.js", + "dependencies": { + "canvas": "^1.6.7", + "express": "^4.16.2", + "moment": "^2.19.2", + "socket.io": "^2.0.4" + }, + "devDependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Moe Alam", + "license": "ISC" +} diff --git a/plugins/openalpr/shinobi-openalpr.js b/plugins/openalpr/shinobi-openalpr.js new file mode 100644 index 0000000..8295208 --- /dev/null +++ b/plugins/openalpr/shinobi-openalpr.js @@ -0,0 +1,413 @@ +// +// Shinobi - OpenALPR Plugin +// Copyright (C) 2016-2025 Moe Alam, moeiscool +// +// # Donate +// +// If you like what I am doing here and want me to continue please consider donating :) +// PayPal : paypal@m03.ca +// +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +//main vars +var fs=require('fs'); +var exec = require('child_process').exec; +var moment = require('moment'); +var Canvas = require('canvas'); +var express = require('express'); +var config=require('./conf.json'); +var http = require('http'), + app = express(), + server = http.createServer(app); +s={ + group:{}, + dir:{ + cascades:__dirname+'/cascades/' + }, + isWin:(process.platform==='win32'), + s:function(json){return JSON.stringify(json,null,3)} +} +s.checkCorrectPathEnding=function(x){ + var length=x.length + if(x.charAt(length-1)!=='/'){ + x=x+'/' + } + return x.replace('__DIR__',__dirname) +} +if(!config.port){config.port=8080} +if(!config.hostPort){config.hostPort=8082} +if(config.systemLog===undefined){config.systemLog=true} +if(config.alprConfig===undefined){config.alprConfig=__dirname+'/openalpr.conf'} +//default stream folder check +if(!config.streamDir){ + if(s.isWin===false){ + config.streamDir='/dev/shm' + }else{ + config.streamDir=config.windowsTempDir + } + if(!fs.existsSync(config.streamDir)){ + config.streamDir=__dirname+'/streams/' + }else{ + config.streamDir+='/streams/' + } +} +s.dir.streams=config.streamDir; +//streams dir +if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); +} +s.gid=function(x){ + if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.detectObject=function(buffer,d,tx){ + var keys = Object.keys(d.mon.detector_cascades); + if(d.mon.detector_lisence_plate==="1"){ + if(!d.mon.detector_lisence_plate_country||d.mon.detector_lisence_plate_country===''){ + d.mon.detector_lisence_plate_country='us' + } + d.tmpFile=s.gid(5)+'.jpg' + if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); + } + d.dir=s.dir.streams+d.ke+'/' + if(!fs.existsSync(d.dir)){ + fs.mkdirSync(d.dir); + } + d.dir=s.dir.streams+d.ke+'/'+d.id+'/' + if(!fs.existsSync(d.dir)){ + fs.mkdirSync(d.dir); + } + fs.writeFile(d.dir+d.tmpFile,buffer,function(err){ + if(err) return s.systemLog(err); + exec('alpr -j --config '+config.alprConfig+' -c '+d.mon.detector_lisence_plate_country+' '+d.dir+d.tmpFile,{encoding:'utf8'},(err, scan, stderr) => { + if(err){ + s.systemLog(err); + }else{ + try{ + try{ + scan=JSON.parse(scan.replace('--(!)Loaded CUDA classifier','').trim()) + }catch(err){ + if(!scan||!scan.results){ + return s.systemLog(scan,err); + } + } +// console.log('scan',scan) + if(scan.results.length>0){ + if(s.isNumberOfTriggersMet(d,2)){ + scan.plates=[] + scan.mats=[] + scan.results.forEach(function(v){ + v.candidates.forEach(function(g,n){ + if(v.candidates[n].matches_template) + delete(v.candidates[n].matches_template) + }) + scan.plates.push({coordinates:v.coordinates,candidates:v.candidates,confidence:v.confidence,plate:v.plate}) + var width = Math.sqrt( Math.pow(v.coordinates[1].x - v.coordinates[0].x, 2) + Math.pow(v.coordinates[1].y - v.coordinates[0].y, 2)); + var height = Math.sqrt( Math.pow(v.coordinates[2].x - v.coordinates[1].x, 2) + Math.pow(v.coordinates[2].y - v.coordinates[1].y, 2)) + scan.mats.push({ + x:v.coordinates[0].x, + y:v.coordinates[0].y, + width:width, + height:height, + tag:v.plate + }) + }) + tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:'licensePlate',reason:'object',matrices:scan.mats,imgHeight:d.mon.detector_scale_y,imgWidth:d.mon.detector_scale_x,frame:d.base64}}) + } + } + }catch(err){ + s.systemLog(scan,err); + } + } + exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'}) + }) + }) + } +} +s.systemLog=function(q,w,e){ + if(w===undefined){return} + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + return console.log(moment().format(),q,w,e) + } +} +s.blenderRegion=function(d,cord,tx){ + d.width = d.image.width; + d.height = d.image.height; + if(!s.group[d.ke][d.id].canvas[cord.name]){ + if(!cord.sensitivity||isNaN(cord.sensitivity)){ + cord.sensitivity=d.mon.detector_sensitivity; + } + s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height); + s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d'); + s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#000'; + s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height); + if(cord.points&&cord.points.length>0){ + s.group[d.ke][d.id].canvasContext[cord.name].beginPath(); + for (var b = 0; b < cord.points.length; b++){ + cord.points[b][0]=parseFloat(cord.points[b][0]); + cord.points[b][1]=parseFloat(cord.points[b][1]); + if(b===0){ + s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]); + }else{ + s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]); + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clip(); + } + } + if(!s.group[d.ke][d.id].canvasContext[cord.name]){ + return + } + s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height); + if(!s.group[d.ke][d.id].blendRegion[cord.name]){ + s.group[d.ke][d.id].blendRegion[cord.name] = new Canvas(d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name] = s.group[d.ke][d.id].blendRegion[cord.name].getContext('2d'); + } + var sourceData = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create an image if the previous image doesn�t exist + if (!s.group[d.ke][d.id].lastRegionImageData[cord.name]) s.group[d.ke][d.id].lastRegionImageData[cord.name] = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create a ImageData instance to receive the blended result + var blendedData = s.group[d.ke][d.id].canvasContext[cord.name].createImageData(d.width, d.height); + // blend the 2 images + s.differenceAccuracy(blendedData.data,sourceData.data,s.group[d.ke][d.id].lastRegionImageData[cord.name].data); + // draw the result in a canvas + s.group[d.ke][d.id].blendRegionContext[cord.name].putImageData(blendedData, 0, 0); + // store the current webcam image + s.group[d.ke][d.id].lastRegionImageData[cord.name] = sourceData; + blendedData = s.group[d.ke][d.id].blendRegionContext[cord.name].getImageData(0, 0, d.width, d.height); + var i = 0; + d.average = 0; + while (i < (blendedData.data.length * 0.25)) { + d.average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]); + ++i; + } + d.average = (d.average / (blendedData.data.length * 0.25))*10; + if (d.average > parseFloat(cord.sensitivity)){ + if(s.isNumberOfTriggersMet(d,2)){ + if(d.mon.detector_use_detect_object==="1"&&d.mon.detector_second!=='1'){ + var buffer=s.group[d.ke][d.id].canvas[cord.name].toBuffer(); + s.detectObject(buffer,d,tx) + }else{ + tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:cord.name,reason:'motion',confidence:d.average,frame:d.base64}}) + } + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name].clearRect(0, 0, d.width, d.height); +} +function blobToBuffer (blob, cb) { + if (typeof Blob === 'undefined' || !(blob instanceof Blob)) { + throw new Error('first argument must be a Blob') + } + if (typeof cb !== 'function') { + throw new Error('second argument must be a function') + } + + var reader = new FileReader() + + function onLoadEnd (e) { + reader.removeEventListener('loadend', onLoadEnd, false) + if (e.error) cb(e.error) + else cb(null, Buffer.from(reader.result)) + } + + reader.addEventListener('loadend', onLoadEnd, false) + reader.readAsArrayBuffer(blob) +} +function fastAbs(value) { + return (value ^ (value >> 31)) - (value >> 31); +} + +function threshold(value) { + return (value > 0x15) ? 0xFF : 0; +} +s.differenceAccuracy=function(target, data1, data2) { + if (data1.length != data2.length) return null; + var i = 0; + while (i < (data1.length * 0.25)) { + var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3; + var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3; + var diff = threshold(fastAbs(average1 - average2)); + target[4 * i] = diff; + target[4 * i + 1] = diff; + target[4 * i + 2] = diff; + target[4 * i + 3] = 0xFF; + ++i; + } +} +s.checkAreas=function(d,tx){ + if(!s.group[d.ke][d.id].cords){ + if(!d.mon.cords){d.mon.cords={}} + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + } + if(d.mon.detector_frame==='1'){ + d.mon.cords.frame={name:'FULL_FRAME',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; + s.group[d.ke][d.id].cords.push(d.mon.cords.frame); + } + for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){ + if(!s.group[d.ke][d.id].cords[b]){return} + s.blenderRegion(d,s.group[d.ke][d.id].cords[b],tx) + } + delete(d.image) +} +s.isNumberOfTriggersMet = function(d,max){ +// ++s.group[d.ke][d.id].numberOfTriggers +// clearTimeout(s.group[d.ke][d.id].numberOfTriggersTimeout) +// s.group[d.ke][d.id].numberOfTriggersTimeout = setTimeout(function(){ +// s.group[d.ke][d.id].numberOfTriggers=0 +// },10000) +// if(s.group[d.ke][d.id].numberOfTriggers>max){ + return true; +// } +// return false; +} +s.MainEventController=function(d,cn,tx){ + switch(d.f){ + case'init_plugin_as_host': + if(!cn){ + console.log('No CN',d) + return + } + if(d.key!==config.key){ + console.log(new Date(),'Plugin Key Mismatch',cn.request.connection.remoteAddress,d) + cn.emit('init',{ok:false}) + cn.disconnect() + }else{ + console.log(new Date(),'Plugin Connected to Client',cn.request.connection.remoteAddress) + cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type}) + } + break; + case'init_monitor': + if(s.group[d.ke]&&s.group[d.ke][d.id]){ + s.group[d.ke][d.id].canvas={} + s.group[d.ke][d.id].canvasContext={} + s.group[d.ke][d.id].blendRegion={} + s.group[d.ke][d.id].blendRegionContext={} + s.group[d.ke][d.id].lastRegionImageData={} + s.group[d.ke][d.id].numberOfTriggers=0 + delete(s.group[d.ke][d.id].cords) + delete(s.group[d.ke][d.id].buffer) + } + break; + case'init_aws_push': +// console.log('init_aws') + s.group[d.ke][d.id].aws={links:[],complete:0,total:d.total,videos:[],tx:tx} + break; + case'frame': + try{ + if(!s.group[d.ke]){ + s.group[d.ke]={} + } + if(!s.group[d.ke][d.id]){ + s.group[d.ke][d.id]={ + canvas:{}, + canvasContext:{}, + lastRegionImageData:{}, + blendRegion:{}, + blendRegionContext:{}, + } + } + if(!s.group[d.ke][d.id].buffer){ + s.group[d.ke][d.id].buffer=[d.frame]; + }else{ + s.group[d.ke][d.id].buffer.push(d.frame) + } + if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ + s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer); + try{ + d.mon.detector_cascades=JSON.parse(d.mon.detector_cascades) + }catch(err){ + + } + if(d.mon.detector_frame_save==="1"){ + d.base64=s.group[d.ke][d.id].buffer.toString('base64') + } + if(d.mon.detector_second==='1'&&d.objectOnly===true){ + s.detectObject(s.group[d.ke][d.id].buffer,d,tx) + }else{ + if(d.mon.detector_use_motion==="1"||d.mon.detector_use_detect_object!=="1"){ + if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){ + d.mon.cords=[] + }else{ + try{ + d.mon.cords=JSON.parse(d.mon.cords) + }catch(err){ + // console.log('d.mon.cords',err,d) + } + } + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + d.mon.cords=d.mon.cords; + d.image = new Canvas.Image; + if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){ + s.systemLog('Must set detector image size') + return + }else{ + d.image.width=d.mon.detector_scale_x; + d.image.height=d.mon.detector_scale_y; + } + d.width=d.image.width; + d.height=d.image.height; + d.image.onload = function() { + s.checkAreas(d,tx); + } + d.image.src = s.group[d.ke][d.id].buffer; + }else{ + s.detectObject(s.group[d.ke][d.id].buffer,d,tx) + } + } + s.group[d.ke][d.id].buffer=null; + } + }catch(err){ + if(err){ + s.systemLog(err) + delete(s.group[d.ke][d.id].buffer) + } + } + break; + } +} +server.listen(config.hostPort); +//web pages and plugin api +app.get('/', function (req, res) { + res.end(''+config.plug+' for Shinobi is running') +}); +//Conector to Shinobi +if(config.mode==='host'){ + //start plugin as host + var io = require('socket.io')(server); + io.attach(server); + s.connectedClients={}; + io.on('connection', function (cn) { + s.connectedClients[cn.id]={id:cn.id} + s.connectedClients[cn.id].tx = function(data){ + data.pluginKey=config.key;data.plug=config.plug; + return io.to(cn.id).emit('ocv',data); + } + cn.on('f',function(d){ + s.MainEventController(d,cn,s.connectedClients[cn.id].tx) + }); + cn.on('disconnect',function(d){ + delete(s.connectedClients[cn.id]) + }) + }); +}else{ + //start plugin as client + if(!config.host){config.host='localhost'} + var io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master + s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} + io.on('connect',function(d){ + s.cx({f:'init',plug:config.plug,notice:config.notice,type:config.type}); + }) + io.on('disconnect',function(d){ + io.connect(); + }) + io.on('f',function(d){ + s.MainEventController(d,null,s.cx) + }) +} \ No newline at end of file diff --git a/plugins/opencv/INSTALL.sh b/plugins/opencv/INSTALL.sh new file mode 100644 index 0000000..cab6113 --- /dev/null +++ b/plugins/opencv/INSTALL.sh @@ -0,0 +1,15 @@ +#!/bin/bash +if [ $(dpkg-query -W -f='${Status}' opencv_version 2>/dev/null | grep -c "ok installed") -eq 0 ]; then + echo "Shinobi - Do ypu want to let the `opencv4nodejs` npm package install OpenCV? " + echo "Only do this if you do not have OpenCV already or will not use a GPU (Hardware Acceleration)." + echo "(y)es or (N)o" + read nodejsinstall + if [ "$nodejsinstall" = "y" ] || [ "$nodejsinstall" = "Y" ]; then + export OPENCV4NODEJS_DISABLE_AUTOBUILD=0 + else + export OPENCV4NODEJS_DISABLE_AUTOBUILD=1 + fi +else + export OPENCV4NODEJS_DISABLE_AUTOBUILD=1 +fi +npm install opencv4nodejs moment express canvas@1.6 --unsafe-perm \ No newline at end of file diff --git a/plugins/opencv/conf.sample.json b/plugins/opencv/conf.sample.json new file mode 100644 index 0000000..1a4b8dc --- /dev/null +++ b/plugins/opencv/conf.sample.json @@ -0,0 +1,9 @@ +{ + "plug":"OpenCV", + "host":"localhost", + "port":8080, + "hostPort":8082, + "key":"change_this_to_something_very_random____make_sure_to_match__/plugins/opencv/conf.json", + "mode":"client", + "type":"detector" +} \ No newline at end of file diff --git a/plugins/opencv/openalpr.conf b/plugins/opencv/openalpr.conf new file mode 100644 index 0000000..070752b --- /dev/null +++ b/plugins/opencv/openalpr.conf @@ -0,0 +1,94 @@ + +; Specify the path to the runtime data directory +runtime_dir = ${CMAKE_INSTALL_PREFIX}/share/openalpr/runtime_data + + +ocr_img_size_percent = 1.33333333 +state_id_img_size_percent = 2.0 + +; Calibrating your camera improves detection accuracy in cases where vehicle plates are captured at a steep angle +; Use the openalpr-utils-calibrate utility to calibrate your fixed camera to adjust for an angle +; Once done, update the prewarp config with the values obtained from the tool +prewarp = + +; detection will ignore plates that are too large. This is a good efficiency technique to use if the +; plates are going to be a fixed distance away from the camera (e.g., you will never see plates that fill +; up the entire image +max_plate_width_percent = 100 +max_plate_height_percent = 100 + +; detection_iteration_increase is the percentage that the LBP frame increases each iteration. +; It must be greater than 1.0. A value of 1.01 means increase by 1%, 1.10 increases it by 10% each time. +; So a 1% increase would be ~10x slower than 10% to process, but it has a higher chance of landing +; directly on the plate and getting a strong detection +detection_iteration_increase = 1.1 + +; The minimum detection strength determines how sure the detection algorithm must be before signaling that +; a plate region exists. Technically this corresponds to LBP nearest neighbors (e.g., how many detections +; are clustered around the same area). For example, 2 = very lenient, 9 = very strict. +detection_strictness = 3 + +; The detection doesn't necessarily need an extremely high resolution image in order to detect plates +; Using a smaller input image should still find the plates and will do it faster +; Tweaking the max_detection_input values will resize the input image if it is larger than these sizes +; max_detection_input_width/height are specified in pixels +max_detection_input_width = 1280 +max_detection_input_height = 720 + +; detector is the technique used to find license plate regions in an image. Value can be set to +; lbpcpu - default LBP-based detector uses the system CPU +; lbpgpu - LBP-based detector that uses Nvidia GPU to increase recognition speed. +; lbpopencl - LBP-based detector that uses OpenCL GPU to increase recognition speed. Requires OpenCV 3.0 +; morphcpu - Experimental detector that detects white rectangles in an image. Does not require training. +detector = lbpgpu + +; If set to true, all results must match a postprocess text pattern if a pattern is available. +; If not, the result is disqualified. +must_match_pattern = 0 + +; Bypasses plate detection. If this is set to 1, the library assumes that each region provided is a likely plate area. +skip_detection = 0 + +; Specifies the full path to an image file that constrains the detection area. Only the plate regions allowed through the mask +; will be analyzed. The mask image must match the resolution of your image to be analyzed. The mask is black and white. +; Black areas will be ignored, white areas will be searched. An empty value means no mask (scan the entire image) +detection_mask_image = + +; OpenALPR can scan the same image multiple times with different randomization. Setting this to a value larger than +; 1 may increase accuracy, but will increase processing time linearly (e.g., analysis_count = 3 is 3x slower) +analysis_count = 1 + +; OpenALPR detects high-contrast plate crops and uses an alternative edge detection technique. Setting this to 0.0 +; would classify ALL images as high-contrast, setting it to 1.0 would classify no images as high-contrast. +contrast_detection_threshold = 0.3 + +max_plate_angle_degrees = 15 + +ocr_min_font_point = 6 + +; Minimum OCR confidence percent to consider. +postprocess_min_confidence = 65 + +; Any OCR character lower than this will also add an equally likely +; chance that the character is incorrect and will be skipped. Value is a confidence percent +postprocess_confidence_skip_level = 80 + + +debug_general = 0 +debug_timing = 0 +debug_detector = 0 +debug_prewarp = 0 +debug_state_id = 0 +debug_plate_lines = 0 +debug_plate_corners = 0 +debug_char_segment = 0 +debug_char_analysis = 0 +debug_color_filter = 0 +debug_ocr = 0 +debug_postprocess = 0 +debug_show_images = 0 +debug_pause_on_frame = 0 + + + + diff --git a/plugins/opencv/shinobi-opencv.js b/plugins/opencv/shinobi-opencv.js new file mode 100644 index 0000000..f51c46e --- /dev/null +++ b/plugins/opencv/shinobi-opencv.js @@ -0,0 +1,465 @@ +// +// Shinobi - OpenCV Plugin +// Copyright (C) 2016-2025 Moe Alam, moeiscool +// +// # Donate +// +// If you like what I am doing here and want me to continue please consider donating :) +// PayPal : paypal@m03.ca +// +process.on('uncaughtException', function (err) { + console.error('uncaughtException',err); +}); +var fs=require('fs'); +var cv=require('opencv4nodejs'); +var exec = require('child_process').exec; +var moment = require('moment'); +var Canvas = require('canvas'); +var express = require('express'); +var http = require('http'), + app = express(), + server = http.createServer(app); +var config=require('./conf.json'); +if(!config.port){config.port=8080} +if(!config.hostPort){config.hostPort=8082} +if(config.systemLog===undefined){config.systemLog=true} +if(config.cascadesDir===undefined){config.cascadesDir=__dirname+'/cascades/'} +if(config.alprConfig===undefined){config.alprConfig=__dirname+'/openalpr.conf'} +s={ + group:{}, + dir:{ + cascades : config.cascadesDir + }, + isWin:(process.platform==='win32'), + foundCascades : { + + } +} +//default stream folder check +if(!config.streamDir){ + if(s.isWin===false){ + config.streamDir='/dev/shm' + }else{ + config.streamDir=config.windowsTempDir + } + if(!fs.existsSync(config.streamDir)){ + config.streamDir=__dirname+'/streams/' + }else{ + config.streamDir+='/streams/' + } +} +s.dir.streams=config.streamDir; +//streams dir +if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); +} +//streams dir +if(!fs.existsSync(s.dir.cascades)){ + fs.mkdirSync(s.dir.cascades); +} +s.gid=function(x){ + if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for( var i=0; i < x; i++ ) + t += p.charAt(Math.floor(Math.random() * p.length)); + return t; +}; +s.findCascades=function(callback){ + var tmp={}; + tmp.foundCascades=[]; + fs.readdir(s.dir.cascades,function(err,files){ + files.forEach(function(cascade,n){ + if(cascade.indexOf('.xml')>-1){ + tmp.foundCascades.push(cascade.replace('.xml','')) + } + }) + s.cascadesInDir=tmp.foundCascades; + callback(tmp.foundCascades) + }) +} +s.findCascades(function(){ + //get cascades +}) +s.detectLicensePlate=function(buffer,d,tx){ + if(!d.mon.detector_lisence_plate_country||d.mon.detector_lisence_plate_country===''){ + d.mon.detector_lisence_plate_country='us' + } + d.tmpFile=s.gid(5)+'.jpg' + if(!fs.existsSync(s.dir.streams)){ + fs.mkdirSync(s.dir.streams); + } + d.dir=s.dir.streams+d.ke+'/' + if(!fs.existsSync(d.dir)){ + fs.mkdirSync(d.dir); + } + d.dir=s.dir.streams+d.ke+'/'+d.id+'/' + if(!fs.existsSync(d.dir)){ + fs.mkdirSync(d.dir); + } + fs.writeFile(d.dir+d.tmpFile,buffer,function(err){ + if(err) return s.systemLog(err); + exec('alpr -j --config '+config.alprConfig+' -c '+d.mon.detector_lisence_plate_country+' '+d.dir+d.tmpFile,{encoding:'utf8'},(err, scan, stderr) => { + if(err){ + s.systemLog(err); + }else{ + try{ + scan=JSON.parse(scan.replace('--(!)Loaded CUDA classifier','').trim()) + }catch(err){ + if(!scan||!scan.results){ + return s.systemLog(scan,err); + } + } + if(scan.results.length>0){ + scan.plates=[] + scan.mats=[] + scan.results.forEach(function(v){ + v.candidates.forEach(function(g,n){ + if(v.candidates[n].matches_template) + delete(v.candidates[n].matches_template) + }) + scan.plates.push({coordinates:v.coordinates,candidates:v.candidates,confidence:v.confidence,plate:v.plate}) + var width = Math.sqrt( Math.pow(v.coordinates[1].x - v.coordinates[0].x, 2) + Math.pow(v.coordinates[1].y - v.coordinates[0].y, 2)); + var height = Math.sqrt( Math.pow(v.coordinates[2].x - v.coordinates[1].x, 2) + Math.pow(v.coordinates[2].y - v.coordinates[1].y, 2)) + scan.mats.push({ + x:v.coordinates[0].x, + y:v.coordinates[0].y, + width:width, + height:height, + tag:v.plate + }) + }) + tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:'licensePlate',reason:'object',matrices:scan.mats,imgHeight:d.mon.detector_scale_y,imgWidth:d.mon.detector_scale_x,frame:d.base64}}) + } + } + exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'}) + }) + }) +} +s.detectObject=function(buffer,d,tx){ + //detect license plate? + if(d.mon.detector_lisence_plate==="1"){ + s.detectLicensePlate(buffer,d,tx) + } + //check selected opencv cascades + if(!d.mon.detector_cascades || d.mon.detector_cascades === '')return; + var selectedCascades = Object.keys(d.mon.detector_cascades); + if(selectedCascades.length > 0){ + cv.imdecodeAsync(buffer,(err,im) => { + if(err){ + console.log(err) + return + } + selectedCascades.forEach(function(cascade){ + var cascadePath = s.dir.cascades+cascade+'.xml' + if(s.foundCascades[cascadePath] === undefined){ + s.foundCascades[cascadePath] = fs.existsSync(cascadePath) + }else if(s.foundCascades[cascadePath] === false){ + return s.systemLog('Attempted to use non existant cascade. : '+cascadePath) + } + var classifier = new cv.CascadeClassifier(cascadePath) + var matrices = classifier.detectMultiScaleGpu(im).objects + if(matrices.length > 0){ + matrices.forEach(function(v,n){ + v.centerX=v.width/2 + v.centerY=v.height/2 + v.centerXnoParent=v.x+(v.width/2) + v.centerYnoParent=v.y+(v.height/2) + }) + s.cx({ + f:'trigger', + id:d.id, + ke:d.ke, + name:cascade, + details:{ + plug:'built-in-opencv', + name:cascade, + reason:'object', + matrices : matrices, + confidence:d.average + }, + imgHeight:d.mon.detector_scale_y, + imgWidth:d.mon.detector_scale_x + }) + } + }) + }); + } +} +s.systemLog=function(q,w,e){ + if(!w){w=''} + if(!e){e=''} + if(config.systemLog===true){ + return console.log(moment().format(),q,w,e) + } +} + +s.blenderRegion=function(d,cord,tx){ + d.width = d.image.width; + d.height = d.image.height; + if(!s.group[d.ke][d.id].canvas[cord.name]){ + if(!cord.sensitivity||isNaN(cord.sensitivity)){ + cord.sensitivity=d.mon.detector_sensitivity; + } + s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height); + s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d'); + s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#000'; + s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height); + if(cord.points&&cord.points.length>0){ + s.group[d.ke][d.id].canvasContext[cord.name].beginPath(); + for (var b = 0; b < cord.points.length; b++){ + cord.points[b][0]=parseFloat(cord.points[b][0]); + cord.points[b][1]=parseFloat(cord.points[b][1]); + if(b===0){ + s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]); + }else{ + s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]); + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clip(); + } + } + if(!s.group[d.ke][d.id].canvasContext[cord.name]){ + return + } + s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height); + if(!s.group[d.ke][d.id].blendRegion[cord.name]){ + s.group[d.ke][d.id].blendRegion[cord.name] = new Canvas(d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name] = s.group[d.ke][d.id].blendRegion[cord.name].getContext('2d'); + } + var sourceData = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create an image if the previous image doesn�t exist + if (!s.group[d.ke][d.id].lastRegionImageData[cord.name]) s.group[d.ke][d.id].lastRegionImageData[cord.name] = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height); + // create a ImageData instance to receive the blended result + var blendedData = s.group[d.ke][d.id].canvasContext[cord.name].createImageData(d.width, d.height); + // blend the 2 images + s.differenceAccuracy(blendedData.data,sourceData.data,s.group[d.ke][d.id].lastRegionImageData[cord.name].data); + // draw the result in a canvas + s.group[d.ke][d.id].blendRegionContext[cord.name].putImageData(blendedData, 0, 0); + // store the current webcam image + s.group[d.ke][d.id].lastRegionImageData[cord.name] = sourceData; + blendedData = s.group[d.ke][d.id].blendRegionContext[cord.name].getImageData(0, 0, d.width, d.height); + var i = 0; + d.average = 0; + while (i < (blendedData.data.length * 0.25)) { + d.average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]); + ++i; + } + d.average = (d.average / (blendedData.data.length * 0.25))*10; + if (d.average > parseFloat(cord.sensitivity)){ + if(d.mon.detector_use_detect_object==="1"&&d.mon.detector_second!=='1'){ + var buffer=s.group[d.ke][d.id].canvas[cord.name].toBuffer(); + s.detectObject(buffer,d,tx) + }else{ + tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:cord.name,reason:'motion',confidence:d.average,frame:d.base64}}) + } + } + s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height); + s.group[d.ke][d.id].blendRegionContext[cord.name].clearRect(0, 0, d.width, d.height); +} +function blobToBuffer (blob, cb) { + if (typeof Blob === 'undefined' || !(blob instanceof Blob)) { + throw new Error('first argument must be a Blob') + } + if (typeof cb !== 'function') { + throw new Error('second argument must be a function') + } + + var reader = new FileReader() + + function onLoadEnd (e) { + reader.removeEventListener('loadend', onLoadEnd, false) + if (e.error) cb(e.error) + else cb(null, Buffer.from(reader.result)) + } + + reader.addEventListener('loadend', onLoadEnd, false) + reader.readAsArrayBuffer(blob) +} +function fastAbs(value) { + return (value ^ (value >> 31)) - (value >> 31); +} + +function threshold(value) { + return (value > 0x15) ? 0xFF : 0; +} +s.differenceAccuracy=function(target, data1, data2) { + if (data1.length != data2.length) return null; + var i = 0; + while (i < (data1.length * 0.25)) { + var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3; + var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3; + var diff = threshold(fastAbs(average1 - average2)); + target[4 * i] = diff; + target[4 * i + 1] = diff; + target[4 * i + 2] = diff; + target[4 * i + 3] = 0xFF; + ++i; + } +} +s.checkAreas=function(d,tx){ + if(!s.group[d.ke][d.id].cords){ + if(!d.mon.cords){d.mon.cords={}} + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + } + if(d.mon.detector_frame==='1'){ + d.mon.cords.frame={name:'FULL_FRAME',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; + s.group[d.ke][d.id].cords.push(d.mon.cords.frame); + } + for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){ + if(!s.group[d.ke][d.id].cords[b]){return} + s.blenderRegion(d,s.group[d.ke][d.id].cords[b],tx) + } + delete(d.image) +} + +s.MainEventController=function(d,cn,tx){ + switch(d.f){ + case'refreshPlugins': + s.findCascades(function(cascades){ + s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:cascades},to:'GRP_'+d.ke}) + }) + break; + case'readPlugins': + s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:s.cascadesInDir},to:'GRP_'+d.ke}) + break; + case'init_plugin_as_host': + if(!cn){ + console.log('No CN',d) + return + } + if(d.key!==config.key){ + console.log(new Date(),'Plugin Key Mismatch',cn.request.connection.remoteAddress,d) + cn.emit('init',{ok:false}) + cn.disconnect() + }else{ + console.log(new Date(),'Plugin Connected to Client',cn.request.connection.remoteAddress) + cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type}) + } + break; + case'init_monitor': + if(s.group[d.ke]&&s.group[d.ke][d.id]){ + s.group[d.ke][d.id].canvas={} + s.group[d.ke][d.id].canvasContext={} + s.group[d.ke][d.id].blendRegion={} + s.group[d.ke][d.id].blendRegionContext={} + s.group[d.ke][d.id].lastRegionImageData={} + s.group[d.ke][d.id].numberOfTriggers=0 + delete(s.group[d.ke][d.id].cords) + delete(s.group[d.ke][d.id].buffer) + } + break; + case'init_aws_push': +// console.log('init_aws') + s.group[d.ke][d.id].aws={links:[],complete:0,total:d.total,videos:[],tx:tx} + break; + case'frame': + try{ + if(!s.group[d.ke]){ + s.group[d.ke]={} + } + if(!s.group[d.ke][d.id]){ + s.group[d.ke][d.id]={ + canvas:{}, + canvasContext:{}, + lastRegionImageData:{}, + blendRegion:{}, + blendRegionContext:{}, + } + } + if(!s.group[d.ke][d.id].buffer){ + s.group[d.ke][d.id].buffer=[d.frame]; + }else{ + s.group[d.ke][d.id].buffer.push(d.frame) + } + if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ + s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer); + try{ + d.mon.detector_cascades=JSON.parse(d.mon.detector_cascades) + }catch(err){ + + } + if(d.mon.detector_frame_save==="1"){ + d.base64=s.group[d.ke][d.id].buffer.toString('base64') + } + if(d.mon.detector_second==='1'&&d.objectOnly===true){ + s.detectObject(s.group[d.ke][d.id].buffer,d,tx) + }else{ + if((d.mon.detector_pam !== '1' && d.mon.detector_use_motion === "1") || d.mon.detector_use_detect_object !== "1"){ + if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){ + d.mon.cords=[] + }else{ + try{ + d.mon.cords=JSON.parse(d.mon.cords) + }catch(err){ + // console.log('d.mon.cords',err,d) + } + } + s.group[d.ke][d.id].cords=Object.values(d.mon.cords); + d.mon.cords=d.mon.cords; + d.image = new Canvas.Image; + if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){ + s.systemLog('Must set detector image size') + return + }else{ + d.image.width=d.mon.detector_scale_x; + d.image.height=d.mon.detector_scale_y; + } + d.width=d.image.width; + d.height=d.image.height; + d.image.onload = function() { + s.checkAreas(d,tx); + } + d.image.src = s.group[d.ke][d.id].buffer; + }else{ + s.detectObject(s.group[d.ke][d.id].buffer,d,tx) + } + } + s.group[d.ke][d.id].buffer=null; + } + }catch(err){ + if(err){ + s.systemLog(err) + delete(s.group[d.ke][d.id].buffer) + } + } + break; + } +} +server.listen(config.hostPort); +//web pages and plugin api +app.get('/', function (req, res) { + res.end(''+config.plug+' for Shinobi is running') +}); +//Conector to Shinobi +if(config.mode==='host'){ + //start plugin as host + var io = require('socket.io')(server); + io.attach(server); + s.connectedClients={}; + io.on('connection', function (cn) { + s.connectedClients[cn.id]={id:cn.id} + s.connectedClients[cn.id].tx = function(data){ + data.pluginKey=config.key;data.plug=config.plug; + return io.to(cn.id).emit('ocv',data); + } + cn.on('f',function(d){ + s.MainEventController(d,cn,s.connectedClients[cn.id].tx) + }); + cn.on('disconnect',function(d){ + delete(s.connectedClients[cn.id]) + }) + }); +}else{ + //start plugin as client + if(!config.host){config.host='localhost'} + var io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master + s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} + io.on('connect',function(d){ + s.cx({f:'init',plug:config.plug,notice:config.notice,type:config.type}); + }) + io.on('disconnect',function(d){ + io.connect(); + }) + io.on('f',function(d){ + s.MainEventController(d,null,s.cx) + }) +} \ No newline at end of file diff --git a/sql/.gitignore b/sql/.gitignore new file mode 100644 index 0000000..87b2844 --- /dev/null +++ b/sql/.gitignore @@ -0,0 +1,2 @@ +monitors.sql +users.sql \ No newline at end of file diff --git a/sql/default_data.sql b/sql/default_data.sql new file mode 100644 index 0000000..5a66924 --- /dev/null +++ b/sql/default_data.sql @@ -0,0 +1,20 @@ +-- -------------------------------------------------------- +-- Host: 66.51.132.100 +-- Server version: 5.7.16-0ubuntu0.16.04.1 - (Ubuntu) +-- Server OS: Linux +-- HeidiSQL Version: 9.3.0.4984 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +-- Dumping data for table ccio.Users: ~0 rows (approximately) +/*!40000 ALTER TABLE `Users` DISABLE KEYS */; +INSERT INTO `Users` (`ke`, `uid`, `auth`, `mail`, `pass`, `details`) VALUES + ('2Df5hBE', 'XDf5hB3', 'ec49f05c1ddc7d818c61b3343c98cbc6', 'ccio@m03.ca', '5f4dcc3b5aa765d61d8327deb882cf99', '{"days":"10"}'); +INSERT INTO `Monitors` (`mid`, `ke`, `name`, `shto`, `shfr`, `details`, `type`, `ext`, `protocol`, `host`, `path`, `port`, `fps`, `mode`, `width`, `height`) VALUES ('bunny', '2Df5hBE', 'Bunny', '[]', '[]', '{"fatal_max":"","notes":"","dir":"","rtsp_transport":"tcp","muser":"","mpass":"","port_force":"0","sfps":"","aduration":"1000000","probesize":"1000000","accelerator":"0","hwaccel":null,"hwaccel_vcodec":"","hwaccel_device":"","stream_type":"hls","stream_mjpeg_clients":"","stream_vcodec":"copy","stream_acodec":"no","hls_time":"","preset_stream":"","hls_list_size":"","signal_check":"","signal_check_log":null,"stream_quality":"","stream_fps":"1","stream_scale_x":"","stream_scale_y":"","rotate_stream":null,"svf":"","stream_timestamp":"0","stream_timestamp_font":"","stream_timestamp_font_size":"","stream_timestamp_color":"","stream_timestamp_box_color":"","stream_timestamp_x":"","stream_timestamp_y":"","stream_watermark":"0","stream_watermark_location":"","stream_watermark_position":null,"snap":"1","snap_fps":"","snap_scale_x":"","snap_scale_y":"","snap_vf":"","vcodec":"copy","crf":"","preset_record":"","acodec":"libvorbis","dqf":null,"cutoff":"10","rotate_record":null,"vf":"","timestamp":"1","timestamp_font":"","timestamp_font_size":"","timestamp_color":"","timestamp_box_color":"","timestamp_x":"","timestamp_y":"","watermark":null,"watermark_location":"","watermark_position":null,"cust_input":"","cust_snap":"","cust_detect":"","cust_stream":"","cust_stream_server":"","cust_record":"","custom_output":"","detector":"0","detector_webhook":null,"detector_webhook_url":"","detector_command_enable":null,"detector_command":"","detector_command_timeout":"","detector_lock_timeout":"","detector_save":null,"detector_frame_save":null,"detector_mail":null,"detector_mail_timeout":"","detector_record_method":null,"detector_trigger":null,"detector_trigger_record_fps":"","detector_timeout":"","watchdog_reset":null,"detector_delete_motionless_videos":null,"detector_send_frames":null,"detector_fps":"","detector_scale_x":"","detector_scale_y":"","detector_use_motion":null,"detector_use_detect_object":null,"detector_frame":null,"detector_sensitivity":"","cords":"","detector_lisence_plate":null,"detector_lisence_plate_country":null,"detector_notrigger":null,"detector_notrigger_mail":null,"detector_notrigger_timeout":"","control":"0","control_base_url":"","control_stop":null,"control_url_stop_timeout":"","control_url_center":"","control_url_left":"","control_url_left_stop":"","control_url_right":"","control_url_right_stop":"","control_url_up":"","control_url_up_stop":"","control_url_down":"","control_url_down_stop":"","control_url_enable_nv":"","control_url_disable_nv":"","control_url_zoom_out":"","control_url_zoom_out_stop":"","control_url_zoom_in":"","control_url_zoom_in_stop":"","groups":"","loglevel":"warning","sqllog":"0","detector_cascades":""}', 'mjpeg', 'mp4', 'http', 'came3.nkansai.ne.jp', '/nphMotionJpeg?Resolution=640x480&Quality=Motion', 81, 15, 'start', 640, 480); +/*!40000 ALTER TABLE `Users` ENABLE KEYS */; +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/docker/01-framework.sql b/sql/docker/01-framework.sql new file mode 100644 index 0000000..cec2dda --- /dev/null +++ b/sql/docker/01-framework.sql @@ -0,0 +1,113 @@ +-- -------------------------------------------------------- +-- Host: 192.168.88.58 +-- Server version: 5.7.17-0ubuntu0.16.04.1 - (Ubuntu) +-- Server OS: Linux +-- HeidiSQL Version: 9.3.0.4984 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; + +-- Dumping structure for table ccio.API +CREATE TABLE IF NOT EXISTS `API` ( + `ke` varchar(50) DEFAULT NULL, + `uid` varchar(50) DEFAULT NULL, + `ip` tinytext, + `code` varchar(100) DEFAULT NULL, + `details` text, + `time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. + + +-- Dumping structure for table ccio.Events +CREATE TABLE IF NOT EXISTS `Events` ( + `ke` varchar(50) DEFAULT NULL, + `mid` varchar(50) DEFAULT NULL, + `details` text, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +-- Data exporting was unselected. + + +-- Dumping structure for table ccio.Logs +CREATE TABLE IF NOT EXISTS `Logs` ( + `ke` varchar(50) DEFAULT NULL, + `mid` varchar(50) DEFAULT NULL, + `info` text, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. + + +-- Dumping structure for table ccio.Monitors +CREATE TABLE IF NOT EXISTS `Monitors` ( + `mid` varchar(50) DEFAULT NULL, + `ke` varchar(50) DEFAULT NULL, + `name` varchar(50) DEFAULT NULL, + `shto` text, + `shfr` text, + `details` longtext, + `type` varchar(50) DEFAULT 'jpeg', + `ext` varchar(50) DEFAULT 'webm', + `protocol` varchar(50) DEFAULT 'http', + `host` varchar(100) DEFAULT '0.0.0.0', + `path` varchar(100) DEFAULT '/', + `port` int(8) DEFAULT '80', + `fps` int(8) DEFAULT '1', + `mode` varchar(15) DEFAULT NULL, + `width` int(11) DEFAULT '640', + `height` int(11) DEFAULT '360' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. + + +-- Dumping structure for table ccio.Presets +CREATE TABLE IF NOT EXISTS `Presets` ( + `ke` varchar(50) DEFAULT NULL, + `name` text, + `details` text, + `type` enum('monitor','event','user') DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. + + +-- Dumping structure for table ccio.Users +CREATE TABLE IF NOT EXISTS `Users` ( + `ke` varchar(50) DEFAULT NULL, + `uid` varchar(50) DEFAULT NULL, + `auth` varchar(50) DEFAULT NULL, + `mail` varchar(100) DEFAULT NULL, + `pass` varchar(100) DEFAULT NULL, + `details` longtext, + UNIQUE KEY `mail` (`mail`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. + + +-- Dumping structure for table ccio.Videos +CREATE TABLE IF NOT EXISTS `Videos` ( + `mid` varchar(50) DEFAULT NULL, + `ke` varchar(50) DEFAULT NULL, + `ext` enum('webm','mp4') DEFAULT NULL, + `time` timestamp NULL DEFAULT NULL, + `duration` float DEFAULT NULL, + `size` float DEFAULT NULL, + `frames` int(11) DEFAULT NULL, + `end` timestamp NULL DEFAULT NULL, + `status` int(1) DEFAULT '0' COMMENT '0:Building,1:Complete,2:Read,3:Archive', + `details` text +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/framework.sql b/sql/framework.sql new file mode 100644 index 0000000..4961e54 --- /dev/null +++ b/sql/framework.sql @@ -0,0 +1,107 @@ +-- -------------------------------------------------------- +-- Host: 192.168.88.37 +-- Server version: 10.1.25-MariaDB- - Ubuntu 17.04 +-- Server OS: debian-linux-gnu +-- HeidiSQL Version: 9.4.0.5125 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8 */; +/*!50503 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; + + +-- Dumping database structure for ccio +CREATE DATABASE IF NOT EXISTS `ccio` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; +USE `ccio`; + +-- Dumping structure for table ccio.API +CREATE TABLE IF NOT EXISTS `API` ( + `ke` varchar(50) DEFAULT NULL, + `uid` varchar(50) DEFAULT NULL, + `ip` tinytext, + `code` varchar(100) DEFAULT NULL, + `details` text, + `time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Events +CREATE TABLE IF NOT EXISTS `Events` ( + `ke` varchar(50) DEFAULT NULL, + `mid` varchar(50) DEFAULT NULL, + `details` text, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Logs +CREATE TABLE IF NOT EXISTS `Logs` ( + `ke` varchar(50) DEFAULT NULL, + `mid` varchar(50) DEFAULT NULL, + `info` text, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Monitors +CREATE TABLE IF NOT EXISTS `Monitors` ( + `mid` varchar(50) DEFAULT NULL, + `ke` varchar(50) DEFAULT NULL, + `name` varchar(50) DEFAULT NULL, + `shto` text, + `shfr` text, + `details` longtext, + `type` varchar(50) DEFAULT 'jpeg', + `ext` varchar(50) DEFAULT 'webm', + `protocol` varchar(50) DEFAULT 'http', + `host` varchar(100) DEFAULT '0.0.0.0', + `path` varchar(100) DEFAULT '/', + `port` int(8) DEFAULT '80', + `fps` int(8) DEFAULT '1', + `mode` varchar(15) DEFAULT NULL, + `width` int(11) DEFAULT '640', + `height` int(11) DEFAULT '360' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Presets +CREATE TABLE IF NOT EXISTS `Presets` ( + `ke` varchar(50) DEFAULT NULL, + `name` text, + `details` text, + `type` enum('monitor','event','user') DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Users +CREATE TABLE IF NOT EXISTS `Users` ( + `ke` varchar(50) DEFAULT NULL, + `uid` varchar(50) DEFAULT NULL, + `auth` varchar(50) DEFAULT NULL, + `mail` varchar(100) DEFAULT NULL, + `pass` varchar(100) DEFAULT NULL, + `details` longtext, + UNIQUE KEY `mail` (`mail`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Videos +CREATE TABLE IF NOT EXISTS `Videos` ( + `mid` varchar(50) DEFAULT NULL, + `ke` varchar(50) DEFAULT NULL, + `ext` enum('webm','mp4') DEFAULT NULL, + `time` timestamp NULL DEFAULT NULL, + `duration` float DEFAULT NULL, + `size` float DEFAULT NULL, + `frames` int(11) DEFAULT NULL, + `end` timestamp NULL DEFAULT NULL, + `status` int(1) DEFAULT '0' COMMENT '0:Building,1:Complete,2:Read,3:Archive', + `details` text +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/mssql/default_data.sql b/sql/mssql/default_data.sql new file mode 100644 index 0000000..e3dae9e --- /dev/null +++ b/sql/mssql/default_data.sql @@ -0,0 +1,20 @@ +-- -------------------------------------------------------- +-- Host: 66.51.132.100 +-- Server version: 5.7.16-0ubuntu0.16.04.1 - (Ubuntu) +-- Server OS: Linux +-- HeidiSQL Version: 9.3.0.4984 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +-- Dumping data for table ccio.Users: ~0 rows (approximately) +/*!40000 ALTER TABLE `Users` DISABLE KEYS */; +INSERT INTO Users ([ke], [uid], [auth], [mail], [pass], [details]) VALUES + ('2Df5hBE', 'XDf5hB3', 'ec49f05c1ddc7d818c61b3343c98cbc6', 'ccio@m03.ca', '5f4dcc3b5aa765d61d8327deb882cf99', '{"days":"10"}'); +INSERT INTO Monitors ([mid], [ke], [name], [shto], [shfr], [details], [type], [ext], [protocol], [host], [path], [port], [fps], [mode], [width], [height]) VALUES ('bunny', '2Df5hBE', 'Bunny', '[]', '[]', '{"fatal_max":"","notes":"","dir":"","rtsp_transport":"tcp","muser":"","mpass":"","port_force":"0","sfps":"","aduration":"1000000","probesize":"1000000","accelerator":"0","hwaccel":null,"hwaccel_vcodec":"","hwaccel_device":"","stream_type":"hls","stream_mjpeg_clients":"","stream_vcodec":"copy","stream_acodec":"no","hls_time":"","preset_stream":"","hls_list_size":"","signal_check":"","signal_check_log":null,"stream_quality":"","stream_fps":"1","stream_scale_x":"","stream_scale_y":"","rotate_stream":null,"svf":"","stream_timestamp":"0","stream_timestamp_font":"","stream_timestamp_font_size":"","stream_timestamp_color":"","stream_timestamp_box_color":"","stream_timestamp_x":"","stream_timestamp_y":"","stream_watermark":"0","stream_watermark_location":"","stream_watermark_position":null,"snap":"1","snap_fps":"","snap_scale_x":"","snap_scale_y":"","snap_vf":"","vcodec":"copy","crf":"","preset_record":"","acodec":"libvorbis","dqf":null,"cutoff":"10","rotate_record":null,"vf":"","timestamp":"1","timestamp_font":"","timestamp_font_size":"","timestamp_color":"","timestamp_box_color":"","timestamp_x":"","timestamp_y":"","watermark":null,"watermark_location":"","watermark_position":null,"cust_input":"","cust_snap":"","cust_detect":"","cust_stream":"","cust_stream_server":"","cust_record":"","custom_output":"","detector":"0","detector_webhook":null,"detector_webhook_url":"","detector_command_enable":null,"detector_command":"","detector_command_timeout":"","detector_lock_timeout":"","detector_save":null,"detector_frame_save":null,"detector_mail":null,"detector_mail_timeout":"","detector_record_method":null,"detector_trigger":null,"detector_trigger_record_fps":"","detector_timeout":"","watchdog_reset":null,"detector_delete_motionless_videos":null,"detector_send_frames":null,"detector_fps":"","detector_scale_x":"","detector_scale_y":"","detector_use_motion":null,"detector_use_detect_object":null,"detector_frame":null,"detector_sensitivity":"","cords":"","detector_lisence_plate":null,"detector_lisence_plate_country":null,"detector_notrigger":null,"detector_notrigger_mail":null,"detector_notrigger_timeout":"","control":"0","control_base_url":"","control_stop":null,"control_url_stop_timeout":"","control_url_center":"","control_url_left":"","control_url_left_stop":"","control_url_right":"","control_url_right_stop":"","control_url_up":"","control_url_up_stop":"","control_url_down":"","control_url_down_stop":"","control_url_enable_nv":"","control_url_disable_nv":"","control_url_zoom_out":"","control_url_zoom_out_stop":"","control_url_zoom_in":"","control_url_zoom_in_stop":"","groups":"","loglevel":"warning","sqllog":"0","detector_cascades":""}', 'mjpeg', 'mp4', 'http', 'came3.nkansai.ne.jp', '/nphMotionJpeg?Resolution=640x480&Quality=Motion', 81, 15, 'start', 640, 480); +/*!40000 ALTER TABLE `Users` ENABLE KEYS */; +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/mssql/framework.sql b/sql/mssql/framework.sql new file mode 100644 index 0000000..d066cce --- /dev/null +++ b/sql/mssql/framework.sql @@ -0,0 +1,107 @@ +-- -------------------------------------------------------- +-- Host: 192.168.88.37 +-- Server version: 10.1.25-MariaDB- - Ubuntu 17.04 +-- Server OS: debian-linux-gnu +-- HeidiSQL Version: 9.4.0.5125 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8 */; +/*!50503 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; + + +-- Dumping database structure for ccio +CREATE DATABASE `ccio` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; +USE ccio; + +-- Dumping structure for table ccio.API +CREATE TABLE API ( + ke varchar(50) DEFAULT NULL, + uid varchar(50) DEFAULT NULL, + ip varchar(255), + code varchar(100) DEFAULT NULL, + details varchar(max), + time datetime2(0) NULL DEFAULT GETDATE() +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Events +CREATE TABLE Events ( + ke varchar(50) DEFAULT NULL, + mid varchar(50) DEFAULT NULL, + details varchar(max), + time datetime2(0) NOT NULL DEFAULT GETDATE() +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Logs +CREATE TABLE Logs ( + ke varchar(50) DEFAULT NULL, + mid varchar(50) DEFAULT NULL, + info varchar(max), + time datetime2(0) NOT NULL DEFAULT GETDATE() +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Monitors +CREATE TABLE Monitors ( + mid varchar(50) DEFAULT NULL, + ke varchar(50) DEFAULT NULL, + name varchar(50) DEFAULT NULL, + shto varchar(max), + shfr varchar(max), + details varchar(max), + type varchar(50) DEFAULT 'jpeg', + ext varchar(50) DEFAULT 'webm', + protocol varchar(50) DEFAULT 'http', + host varchar(100) DEFAULT '0.0.0.0', + path varchar(100) DEFAULT '/', + port int DEFAULT '80', + fps int DEFAULT '1', + mode varchar(15) DEFAULT NULL, + width int DEFAULT '640', + height int DEFAULT '360' +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Presets +CREATE TABLE Presets ( + ke varchar(50) DEFAULT NULL, + name varchar(max), + details varchar(max), + type enum('monitor','event','user') DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Users +CREATE TABLE Users ( + ke varchar(50) DEFAULT NULL, + uid varchar(50) DEFAULT NULL, + auth varchar(50) DEFAULT NULL, + mail varchar(100) DEFAULT NULL, + pass varchar(100) DEFAULT NULL, + details varchar(max), + CONSTRAINT mail UNIQUE (mail) +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Videos +CREATE TABLE Videos ( + mid varchar(50) DEFAULT NULL, + ke varchar(50) DEFAULT NULL, + ext enum('webm','mp4') DEFAULT NULL, + time datetime2(0) NULL DEFAULT NULL, + duration float DEFAULT NULL, + size float DEFAULT NULL, + frames int DEFAULT NULL, + end datetime2(0) NULL DEFAULT NULL, + status int DEFAULT '0' , + details varchar(max) +) ; + +-- Data exporting was unselected. +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/mssql/user.sql b/sql/mssql/user.sql new file mode 100644 index 0000000..399511d --- /dev/null +++ b/sql/mssql/user.sql @@ -0,0 +1,3 @@ +CREATE USER 'majesticflame'@'127.0.0.1' IDENTIFIED BY ''; +GRANT ALL PRIVILEGES ON ccio.* TO 'majesticflame'@'127.0.0.1'; +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/sql/postgresql/default_data.sql b/sql/postgresql/default_data.sql new file mode 100644 index 0000000..3cf0d48 --- /dev/null +++ b/sql/postgresql/default_data.sql @@ -0,0 +1,20 @@ +-- -------------------------------------------------------- +-- Host: 66.51.132.100 +-- Server version: 5.7.16-0ubuntu0.16.04.1 - (Ubuntu) +-- Server OS: Linux +-- HeidiSQL Version: 9.3.0.4984 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +-- Dumping data for table ccio.Users: ~0 rows (approximately) +/*!40000 ALTER TABLE `Users` DISABLE KEYS */; +INSERT INTO Users (ke, uid, auth, mail, pass, details) VALUES + ('2Df5hBE', 'XDf5hB3', 'ec49f05c1ddc7d818c61b3343c98cbc6', 'ccio@m03.ca', '5f4dcc3b5aa765d61d8327deb882cf99', '{"days":"10"}'); +INSERT INTO Monitors (mid, ke, name, shto, shfr, details, type, ext, protocol, host, path, port, fps, mode, width, height) VALUES ('bunny', '2Df5hBE', 'Bunny', '[]', '[]', '{"fatal_max":"","notes":"","dir":"","rtsp_transport":"tcp","muser":"","mpass":"","port_force":"0","sfps":"","aduration":"1000000","probesize":"1000000","accelerator":"0","hwaccel":null,"hwaccel_vcodec":"","hwaccel_device":"","stream_type":"hls","stream_mjpeg_clients":"","stream_vcodec":"copy","stream_acodec":"no","hls_time":"","preset_stream":"","hls_list_size":"","signal_check":"","signal_check_log":null,"stream_quality":"","stream_fps":"1","stream_scale_x":"","stream_scale_y":"","rotate_stream":null,"svf":"","stream_timestamp":"0","stream_timestamp_font":"","stream_timestamp_font_size":"","stream_timestamp_color":"","stream_timestamp_box_color":"","stream_timestamp_x":"","stream_timestamp_y":"","stream_watermark":"0","stream_watermark_location":"","stream_watermark_position":null,"snap":"1","snap_fps":"","snap_scale_x":"","snap_scale_y":"","snap_vf":"","vcodec":"copy","crf":"","preset_record":"","acodec":"libvorbis","dqf":null,"cutoff":"10","rotate_record":null,"vf":"","timestamp":"1","timestamp_font":"","timestamp_font_size":"","timestamp_color":"","timestamp_box_color":"","timestamp_x":"","timestamp_y":"","watermark":null,"watermark_location":"","watermark_position":null,"cust_input":"","cust_snap":"","cust_detect":"","cust_stream":"","cust_stream_server":"","cust_record":"","custom_output":"","detector":"0","detector_webhook":null,"detector_webhook_url":"","detector_command_enable":null,"detector_command":"","detector_command_timeout":"","detector_lock_timeout":"","detector_save":null,"detector_frame_save":null,"detector_mail":null,"detector_mail_timeout":"","detector_record_method":null,"detector_trigger":null,"detector_trigger_record_fps":"","detector_timeout":"","watchdog_reset":null,"detector_delete_motionless_videos":null,"detector_send_frames":null,"detector_fps":"","detector_scale_x":"","detector_scale_y":"","detector_use_motion":null,"detector_use_detect_object":null,"detector_frame":null,"detector_sensitivity":"","cords":"","detector_lisence_plate":null,"detector_lisence_plate_country":null,"detector_notrigger":null,"detector_notrigger_mail":null,"detector_notrigger_timeout":"","control":"0","control_base_url":"","control_stop":null,"control_url_stop_timeout":"","control_url_center":"","control_url_left":"","control_url_left_stop":"","control_url_right":"","control_url_right_stop":"","control_url_up":"","control_url_up_stop":"","control_url_down":"","control_url_down_stop":"","control_url_enable_nv":"","control_url_disable_nv":"","control_url_zoom_out":"","control_url_zoom_out_stop":"","control_url_zoom_in":"","control_url_zoom_in_stop":"","groups":"","loglevel":"warning","sqllog":"0","detector_cascades":""}', 'mjpeg', 'mp4', 'http', 'came3.nkansai.ne.jp', '/nphMotionJpeg?Resolution=640x480&Quality=Motion', 81, 15, 'start', 640, 480); +/*!40000 ALTER TABLE `Users` ENABLE KEYS */; +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/postgresql/framework.sql b/sql/postgresql/framework.sql new file mode 100644 index 0000000..21773d8 --- /dev/null +++ b/sql/postgresql/framework.sql @@ -0,0 +1,107 @@ +-- -------------------------------------------------------- +-- Host: 192.168.88.37 +-- Server version: 10.1.25-MariaDB- - Ubuntu 17.04 +-- Server OS: debian-linux-gnu +-- HeidiSQL Version: 9.4.0.5125 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8 */; +/*!50503 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; + + +-- Dumping database structure for ccio +CREATE DATABASE `ccio` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; +USE ccio; + +-- Dumping structure for table ccio.API +CREATE TABLE IF NOT EXISTS API ( + ke varchar(50) DEFAULT NULL, + uid varchar(50) DEFAULT NULL, + ip tinytext, + code varchar(100) DEFAULT NULL, + details text, + time timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Events +CREATE TABLE IF NOT EXISTS Events ( + ke varchar(50) DEFAULT NULL, + mid varchar(50) DEFAULT NULL, + details text, + time timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Logs +CREATE TABLE IF NOT EXISTS Logs ( + ke varchar(50) DEFAULT NULL, + mid varchar(50) DEFAULT NULL, + info text, + time timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Monitors +CREATE TABLE IF NOT EXISTS Monitors ( + mid varchar(50) DEFAULT NULL, + ke varchar(50) DEFAULT NULL, + name varchar(50) DEFAULT NULL, + shto text, + shfr text, + details text, + type varchar(50) DEFAULT 'jpeg', + ext varchar(50) DEFAULT 'webm', + protocol varchar(50) DEFAULT 'http', + host varchar(100) DEFAULT '0.0.0.0', + path varchar(100) DEFAULT '/', + port int DEFAULT '80', + fps int DEFAULT '1', + mode varchar(15) DEFAULT NULL, + width int DEFAULT '640', + height int DEFAULT '360' +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Presets +CREATE TABLE IF NOT EXISTS Presets ( + ke varchar(50) DEFAULT NULL, + name text, + details text, + type enum('monitor','event','user') DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Users +CREATE TABLE IF NOT EXISTS Users ( + ke varchar(50) DEFAULT NULL, + uid varchar(50) DEFAULT NULL, + auth varchar(50) DEFAULT NULL, + mail varchar(100) DEFAULT NULL, + pass varchar(100) DEFAULT NULL, + details text, + CONSTRAINT mail UNIQUE (mail) +) ; + +-- Data exporting was unselected. +-- Dumping structure for table ccio.Videos +CREATE TABLE IF NOT EXISTS Videos ( + mid varchar(50) DEFAULT NULL, + ke varchar(50) DEFAULT NULL, + ext enum('webm','mp4') DEFAULT NULL, + time timestamp(0) NULL DEFAULT NULL, + duration double precision DEFAULT NULL, + size double precision DEFAULT NULL, + frames int DEFAULT NULL, + end timestamp(0) NULL DEFAULT NULL, + status int DEFAULT '0' , + details text +) ; + +-- Data exporting was unselected. +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/postgresql/user.sql b/sql/postgresql/user.sql new file mode 100644 index 0000000..399511d --- /dev/null +++ b/sql/postgresql/user.sql @@ -0,0 +1,3 @@ +CREATE USER 'majesticflame'@'127.0.0.1' IDENTIFIED BY ''; +GRANT ALL PRIVILEGES ON ccio.* TO 'majesticflame'@'127.0.0.1'; +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/sql/shinobi.sample.sqlite b/sql/shinobi.sample.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..2796be7b20f18543d31fb234bb1a23f32428034f GIT binary patch literal 40960 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 + ffmpegString='-rtsp_transport tcp '+ffmpegString +} +console.log('Executing : '+config.ffmpegDir+' '+ffmpegString) +var ffmpeg = spawn(config.ffmpegDir,ffmpegString.split(' '),{stdio:['pipe','pipe','pipe','pipe','pipe']}); +ffmpeg.on('close', function (buffer) { + console.log('ffmpeg died') +}) +//// FFMPEG Error Logs +ffmpeg.stderr.on('data', function (buffer) { + console.log(buffer.toString()) +}); +//data from pipe:1 output of ffmpeg + +var onFFmpegData = function (buffer) { + initFirstChunk('1',buffer) + onFFmpegData = function (buffer) { + initEmitter('1').emit('data',buffer) + } + onFFmpegData(buffer) +} + +ffmpeg.stdio[1].on('data', onFFmpegData); \ No newline at end of file diff --git a/tools/FLV Stream/flv.min.js b/tools/FLV Stream/flv.min.js new file mode 100644 index 0000000..94f1ddc --- /dev/null +++ b/tools/FLV Stream/flv.min.js @@ -0,0 +1,7 @@ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.flvjs=e()}}(function(){var e;return function e(t,n,i){function r(a,o){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!o&&u)return u(a,!0);if(s)return s(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var d=n[a]={exports:{}};t[a][0].call(d.exports,function(e){var n=t[a][1][e];return r(n||e)},d,d.exports,e,t,n,i)}return n[a].exports}for(var s="function"==typeof require&&require,a=0;a0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},i.prototype.on=i.prototype.addListener,i.prototype.once=function(e,t){function n(){this.removeListener(e,n),i||(i=!0,t.apply(this,arguments))}if(!r(t))throw TypeError("listener must be a function");var i=!1;return n.listener=t,this.on(e,n),this},i.prototype.removeListener=function(e,t){var n,i,s,o;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],s=n.length,i=-1,n===t||r(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(a(n)){for(o=s;o-- >0;)if(n[o]===t||n[o].listener&&n[o].listener===t){i=o;break}if(i<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(i,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},i.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],r(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},i.prototype.listeners=function(e){return this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},i.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(r(t))return 1;if(t)return t.length}return 0},i.listenerCount=function(e,t){return e.listenerCount(t)}},{}],3:[function(e,t,n){function i(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function s(e){if(h===setTimeout)return setTimeout(e,0);if((h===i||!h)&&setTimeout)return h=setTimeout,setTimeout(e,0);try{return h(e,0)}catch(t){try{return h.call(null,e,0)}catch(t){return h.call(this,e,0)}}}function a(e){if(f===clearTimeout)return clearTimeout(e);if((f===r||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(e);try{return f(e)}catch(t){try{return f.call(null,e)}catch(t){return f.call(this,e)}}}function o(){p&&_&&(p=!1,_.length?m=_.concat(m):v=-1,m.length&&u())}function u(){if(!p){var e=s(o);p=!0;for(var t=m.length;t;){for(_=m,m=[];++v1)for(var n=1;n=e[r]&&t0&&e[0].originalDts=t[r].dts&&et[i].lastSample.originalDts&&e=t[i].lastSample.originalDts&&(i===t.length-1||i0&&(r=this._searchNearestSegmentBefore(n.originalBeginDts)+1),this._lastAppendLocation=r,this._list.splice(r,0,n)}},{key:"getLastSegmentBefore",value:function(e){var t=this._searchNearestSegmentBefore(e);return t>=0?this._list[t]:null}},{key:"getLastSampleBefore",value:function(e){var t=this.getLastSegmentBefore(e);return null!=t?t.lastSample:null}},{key:"getLastSyncPointBefore",value:function(e){for(var t=this._searchNearestSegmentBefore(e),n=this._list[t].syncPoints;0===n.length&&t>0;)t--,n=this._list[t].syncPoints;return n.length>0?n[n.length-1]:null}},{key:"type",get:function(){return this._type}},{key:"length",get:function(){return this._list.length}}]),e}()},{}],9:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0&&(i+=";codecs="+n.codec);var r=!1;if(l.default.v(this.TAG,"Received Initialization Segment, mimeType: "+i),this._lastInitSegments[n.type]=n,i!==this._mimeTypes[n.type]){if(this._mimeTypes[n.type])l.default.v(this.TAG,"Notice: "+n.type+" mimeType changed, origin: "+this._mimeTypes[n.type]+", target: "+i);else{r=!0;try{var s=this._sourceBuffers[n.type]=this._mediaSource.addSourceBuffer(i);s.addEventListener("error",this.e.onSourceBufferError),s.addEventListener("updateend",this.e.onSourceBufferUpdateEnd)}catch(e){return l.default.e(this.TAG,e.message),void this._emitter.emit(c.default.ERROR,{code:e.code,msg:e.message})}}this._mimeTypes[n.type]=i}t||this._pendingSegments[n.type].push(n),r||this._sourceBuffers[n.type]&&!this._sourceBuffers[n.type].updating&&this._doAppendSegments(),h.default.safari&&"audio/mpeg"===n.container&&n.mediaDuration>0&&(this._requireSetMediaDuration=!0,this._pendingMediaDuration=n.mediaDuration/1e3,this._updateMediaSourceDuration())}},{key:"appendMediaSegment",value:function(e){var t=e;this._pendingSegments[t.type].push(t),this._config.autoCleanupSourceBuffer&&this._needCleanupSourceBuffer()&&this._doCleanupSourceBuffer();var n=this._sourceBuffers[t.type];!n||n.updating||this._hasPendingRemoveRanges()||this._doAppendSegments()}},{key:"seek",value:function(e){for(var t in this._sourceBuffers)if(this._sourceBuffers[t]){var n=this._sourceBuffers[t];if("open"===this._mediaSource.readyState)try{n.abort()}catch(e){l.default.e(this.TAG,e.message)}this._idrList.clear();var i=this._pendingSegments[t];if(i.splice(0,i.length),"closed"!==this._mediaSource.readyState){for(var r=0;r=1&&e-i.start(0)>=this._config.autoCleanupMaxBackwardDuration)return!0}}return!1}},{key:"_doCleanupSourceBuffer",value:function(){var e=this._mediaElement.currentTime;for(var t in this._sourceBuffers){var n=this._sourceBuffers[t];if(n){for(var i=n.buffered,r=!1,s=0;s=this._config.autoCleanupMaxBackwardDuration){r=!0;var u=e-this._config.autoCleanupMinBackwardDuration;this._pendingRemoveRanges[t].push({start:a,end:u})}}else o0&&(isNaN(t)||n>t)&&(l.default.v(this.TAG,"Update MediaSource duration from "+t+" to "+n),this._mediaSource.duration=n),this._requireSetMediaDuration=!1,this._pendingMediaDuration=0}}},{key:"_doRemoveRanges",value:function(){for(var e in this._pendingRemoveRanges)if(this._sourceBuffers[e]&&!this._sourceBuffers[e].updating)for(var t=this._sourceBuffers[e],n=this._pendingRemoveRanges[e];n.length&&!t.updating;){var i=n.shift();t.remove(i.start,i.end)}}},{key:"_doAppendSegments",value:function(){var e=this._pendingSegments;for(var t in e)if(this._sourceBuffers[t]&&!this._sourceBuffers[t].updating&&e[t].length>0){var n=e[t].shift();if(n.timestampOffset){var i=this._sourceBuffers[t].timestampOffset,r=n.timestampOffset/1e3,s=Math.abs(i-r);s>.1&&(l.default.v(this.TAG,"Update MPEG audio timestampOffset from "+i+" to "+r),this._sourceBuffers[t].timestampOffset=r),delete n.timestampOffset}if(!n.data||0===n.data.byteLength)continue;try{this._sourceBuffers[t].appendBuffer(n.data),this._isBufferFull=!1,"video"===t&&n.hasOwnProperty("info")&&this._idrList.appendArray(n.info.syncPoints)}catch(e){this._pendingSegments[t].unshift(n),22===e.code?(this._isBufferFull||this._emitter.emit(c.default.BUFFER_FULL),this._isBufferFull=!0):(l.default.e(this.TAG,e.message),this._emitter.emit(c.default.ERROR,{code:e.code,msg:e.message}))}}}},{key:"_onSourceOpen",value:function(){if(l.default.v(this.TAG,"MediaSource onSourceOpen"),this._mediaSource.removeEventListener("sourceopen",this.e.onSourceOpen),this._pendingSourceBufferInit.length>0)for(var e=this._pendingSourceBufferInit;e.length;){var t=e.shift();this.appendInitSegment(t,!0)}this._hasPendingSegments()&&this._doAppendSegments(),this._emitter.emit(c.default.SOURCE_OPEN)}},{key:"_onSourceEnded",value:function(){l.default.v(this.TAG,"MediaSource onSourceEnded")}},{key:"_onSourceClose",value:function(){l.default.v(this.TAG,"MediaSource onSourceClose"),this._mediaSource&&null!=this.e&&(this._mediaSource.removeEventListener("sourceopen",this.e.onSourceOpen),this._mediaSource.removeEventListener("sourceended",this.e.onSourceEnded),this._mediaSource.removeEventListener("sourceclose",this.e.onSourceClose))}},{key:"_hasPendingSegments",value:function(){var e=this._pendingSegments;return e.video.length>0||e.audio.length>0}},{key:"_hasPendingRemoveRanges",value:function(){var e=this._pendingRemoveRanges;return e.video.length>0||e.audio.length>0}},{key:"_onSourceBufferUpdateEnd",value:function(){this._requireSetMediaDuration?this._updateMediaSourceDuration():this._hasPendingRemoveRanges()?this._doRemoveRanges():this._hasPendingSegments()?this._doAppendSegments():this._hasPendingEos&&this.endOfStream(),this._emitter.emit(c.default.UPDATE_END)}},{key:"_onSourceBufferError",value:function(e){l.default.e(this.TAG,"SourceBuffer Error: "+e)}}]),e}();n.default=p},{"../utils/browser.js":39,"../utils/exception.js":40,"../utils/logger.js":41,"./media-segment-info.js":8,"./mse-events.js":10,events:2}],10:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i={ERROR:"error",SOURCE_OPEN:"source_open",UPDATE_END:"update_end",BUFFER_FULL:"buffer_full"};n.default=i},{}],11:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0)this._demuxer.bindDataSource(this._ioctl),this._demuxer.timestampBase=this._mediaDataSource.segments[this._currentSegmentIndex].timestampBase,r=this._demuxer.parseChunks(e,t);else if((i=m.default.probe(e)).match){this._demuxer=new m.default(i,this._config),this._remuxer||(this._remuxer=new v.default(this._config));var s=this._mediaDataSource;void 0==s.duration||isNaN(s.duration)||(this._demuxer.overridedDuration=s.duration),"boolean"==typeof s.hasAudio&&(this._demuxer.overridedHasAudio=s.hasAudio),"boolean"==typeof s.hasVideo&&(this._demuxer.overridedHasVideo=s.hasVideo),this._demuxer.timestampBase=s.segments[this._currentSegmentIndex].timestampBase,this._demuxer.onError=this._onDemuxException.bind(this),this._demuxer.onMediaInfo=this._onMediaInfo.bind(this),this._remuxer.bindDataSource(this._demuxer.bindDataSource(this._ioctl)),this._remuxer.onInitSegment=this._onRemuxerInitSegmentArrival.bind(this),this._remuxer.onMediaSegment=this._onRemuxerMediaSegmentArrival.bind(this),r=this._demuxer.parseChunks(e,t)}else i=null,l.default.e(this.TAG,"Non-FLV, Unsupported media type!"),Promise.resolve().then(function(){n._internalAbort()}),this._emitter.emit(k.default.DEMUX_ERROR,y.default.FORMAT_UNSUPPORTED,"Non-FLV, Unsupported media type"),r=0;return r}},{key:"_onMediaInfo",value:function(e){var t=this;null==this._mediaInfo&&(this._mediaInfo=Object.assign({},e),this._mediaInfo.keyframesIndex=null,this._mediaInfo.segments=[],this._mediaInfo.segmentCount=this._mediaDataSource.segments.length,Object.setPrototypeOf(this._mediaInfo,c.default.prototype));var n=Object.assign({},e);Object.setPrototypeOf(n,c.default.prototype),this._mediaInfo.segments[this._currentSegmentIndex]=n,this._reportSegmentMediaInfo(this._currentSegmentIndex),null!=this._pendingSeekTime&&Promise.resolve().then(function(){var e=t._pendingSeekTime;t._pendingSeekTime=null,t.seek(e)})}},{key:"_onIOSeeked",value:function(){this._remuxer.insertDiscontinuity()}},{key:"_onIOComplete",value:function(e){var t=e,n=t+1;n0&&n[0].originalDts===i&&(i=n[0].pts),this._emitter.emit(k.default.RECOMMEND_SEEKPOINT,i)}}},{key:"_enableStatisticsReporter",value:function(){null==this._statisticsReporter&&(this._statisticsReporter=self.setInterval(this._reportStatisticsInfo.bind(this),this._config.statisticsInfoReportInterval))}},{key:"_disableStatisticsReporter",value:function(){this._statisticsReporter&&(self.clearInterval(this._statisticsReporter),this._statisticsReporter=null)}},{key:"_reportSegmentMediaInfo",value:function(e){var t=this._mediaInfo.segments[e],n=Object.assign({},t);n.duration=this._mediaInfo.duration,n.segmentCount=this._mediaInfo.segmentCount,delete n.segments,delete n.keyframesIndex,this._emitter.emit(k.default.MEDIA_INFO,n)}},{key:"_reportStatisticsInfo",value:function(){var e={};e.url=this._ioctl.currentURL,e.hasRedirect=this._ioctl.hasRedirect,e.hasRedirect&&(e.redirectedURL=this._ioctl.currentRedirectedURL),e.speed=this._ioctl.currentSpeed,e.loaderType=this._ioctl.loaderType,e.currentSegmentIndex=this._currentSegmentIndex,e.totalSegmentCount=this._mediaDataSource.segments.length,this._emitter.emit(k.default.STATISTICS_INFO,e)}}]),e}());n.default=L},{"../demux/demux-errors.js":16,"../demux/flv-demuxer.js":18,"../io/io-controller.js":23,"../io/loader.js":24,"../remux/mp4-remuxer.js":38,"../utils/browser.js":39,"../utils/logger.js":41,"./media-info.js":7,"./transmuxing-events.js":13,events:2}],13:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i={IO_ERROR:"io_error",DEMUX_ERROR:"demux_error",INIT_SEGMENT:"init_segment",MEDIA_SEGMENT:"media_segment",LOADING_COMPLETE:"loading_complete",RECOVERED_EARLY_EOF:"recovered_early_eof",MEDIA_INFO:"media_info",STATISTICS_INFO:"statistics_info",RECOMMEND_SEEKPOINT:"recommend_seekpoint"};n.default=i},{}],14:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(n,"__esModule",{value:!0});var r=e("../utils/logger.js"),s=(i(r),e("../utils/logging-control.js")),a=i(s),o=e("../utils/polyfill.js"),u=i(o),l=e("./transmuxing-controller.js"),d=i(l),h=e("./transmuxing-events.js"),f=i(h),c=function(e){function t(t,n){var i={msg:f.default.INIT_SEGMENT,data:{type:t,data:n}};e.postMessage(i,[n.data])}function n(t,n){var i={msg:f.default.MEDIA_SEGMENT,data:{type:t,data:n}};e.postMessage(i,[n.data])}function i(){var t={msg:f.default.LOADING_COMPLETE};e.postMessage(t)}function r(){var t={msg:f.default.RECOVERED_EARLY_EOF};e.postMessage(t)}function s(t){var n={msg:f.default.MEDIA_INFO,data:t};e.postMessage(n)}function o(t){var n={msg:f.default.STATISTICS_INFO,data:t};e.postMessage(n)}function l(t,n){e.postMessage({msg:f.default.IO_ERROR,data:{type:t,info:n}})}function h(t,n){e.postMessage({msg:f.default.DEMUX_ERROR,data:{type:t,info:n}})}function c(t){e.postMessage({msg:f.default.RECOMMEND_SEEKPOINT,data:t})}function _(t,n){e.postMessage({msg:"logcat_callback",data:{type:t,logcat:n}})}var m=null,p=_.bind(this);u.default.install(),e.addEventListener("message",function(u){switch(u.data.cmd){case"init":m=new d.default(u.data.param[0],u.data.param[1]),m.on(f.default.IO_ERROR,l.bind(this)),m.on(f.default.DEMUX_ERROR,h.bind(this)),m.on(f.default.INIT_SEGMENT,t.bind(this)),m.on(f.default.MEDIA_SEGMENT,n.bind(this)),m.on(f.default.LOADING_COMPLETE,i.bind(this)),m.on(f.default.RECOVERED_EARLY_EOF,r.bind(this)),m.on(f.default.MEDIA_INFO,s.bind(this)),m.on(f.default.STATISTICS_INFO,o.bind(this)),m.on(f.default.RECOMMEND_SEEKPOINT,c.bind(this));break;case"destroy":m&&(m.destroy(),m=null),e.postMessage({msg:"destroyed"});break;case"start":m.start();break;case"stop":m.stop();break;case"seek":m.seek(u.data.param);break;case"pause":m.pause();break;case"resume":m.resume();break;case"logging_config":var _=u.data.param;a.default.applyConfig(_),!0===_.enableCallback?a.default.addLogListener(p):a.default.removeLogListener(p)}})};n.default=c},{"../utils/logger.js":41,"../utils/logging-control.js":42,"../utils/polyfill.js":43,"./transmuxing-controller.js":12,"./transmuxing-events.js":13}],15:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0?(0,l.default)(new Uint8Array(e,t+2,r)):"",{data:s,size:2+r}}},{key:"parseLongString",value:function(e,t,n){if(n<4)throw new d.IllegalStateException("Data not enough when parse LongString");var i=new DataView(e,t,n),r=i.getUint32(0,!h),s=void 0;return s=r>0?(0,l.default)(new Uint8Array(e,t+4,r)):"",{data:s,size:4+r}}},{key:"parseDate",value:function(e,t,n){if(n<10)throw new d.IllegalStateException("Data size invalid when parse Date");var i=new DataView(e,t,n),r=i.getFloat64(0,!h);return r+=60*i.getInt16(8,!h)*1e3,{data:new Date(r),size:10}}},{key:"parseValue",value:function(t,n,i){if(i<1)throw new d.IllegalStateException("Data not enough when parse Value");var r=new DataView(t,n,i),s=1,a=r.getUint8(0),u=void 0,l=!1;try{switch(a){case 0:u=r.getFloat64(1,!h),s+=8;break;case 1:u=!!r.getUint8(1),s+=1;break;case 2:var f=e.parseString(t,n+1,i-1);u=f.data,s+=f.size;break;case 3:u={};var c=0;for(9==(16777215&r.getUint32(i-4,!h))&&(c=3);s32)throw new s.InvalidArgumentException("ExpGolomb: readBits() bits exceeded max 32bits!");if(e<=this._current_word_bits_left){var t=this._current_word>>>32-e;return this._current_word<<=e,this._current_word_bits_left-=e,t}var n=this._current_word_bits_left?this._current_word:0;n>>>=32-this._current_word_bits_left;var i=e-this._current_word_bits_left;this._fillCurrentWord();var r=Math.min(i,this._current_word_bits_left),a=this._current_word>>>32-r;return this._current_word<<=r,this._current_word_bits_left-=r,n=n<>>e))return this._current_word<<=e,this._current_word_bits_left-=e,e;return this._fillCurrentWord(),e+this._skipLeadingZero()}},{key:"readUEG",value:function(){var e=this._skipLeadingZero();return this.readBits(e+1)-1}},{key:"readSEG",value:function(){var e=this.readUEG();return 1&e?e+1>>>1:-1*(e>>>1)}}]),e}();n.default=a},{"../utils/exception.js":40}],18:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]}Object.defineProperty(n,"__esModule",{value:!0});var a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=function(){function e(e,t){for(var n=0;n13))return 0;i=e.probe(t).dataOffset}if(this._firstParse){this._firstParse=!1,n+i!==this._dataOffset&&l.default.w(this.TAG,"First time parsing but chunk byteStart invalid!");0!==new DataView(t,i).getUint32(0,!r)&&l.default.w(this.TAG,"PrevTagSize0 !== 0 !!!"),i+=4}for(;it.byteLength)break;var a=s.getUint8(0),o=16777215&s.getUint32(0,!r);if(i+11+o+4>t.byteLength)break;if(8===a||9===a||18===a){var u=s.getUint8(4),d=s.getUint8(5),h=s.getUint8(6),f=s.getUint8(7),c=h|d<<8|u<<16|f<<24;0!==(16777215&s.getUint32(7,!r))&&l.default.w(this.TAG,"Meet tag which has StreamID != 0!");var _=i+11;switch(a){case 8:this._parseAudioData(t,_,o,c);break;case 9:this._parseVideoData(t,_,o,c,n+i);break;case 18:this._parseScriptData(t,_,o)}var m=s.getUint32(11+o,!r);m!==11+o&&l.default.w(this.TAG,"Invalid PrevTagSize "+m),i+=11+o+4}else l.default.w(this.TAG,"Unsupported tag type "+a+", skipped"),i+=11+o+4}return this._isInitialMetadataDispatched()&&this._dispatch&&(this._audioTrack.length||this._videoTrack.length)&&this._onDataAvailable(this._audioTrack,this._videoTrack),i}},{key:"_parseScriptData",value:function(e,t,n){var i=h.default.parseScriptData(e,t,n);if(i.hasOwnProperty("onMetaData")){if(null==i.onMetaData||"object"!==a(i.onMetaData))return void l.default.w(this.TAG,"Invalid onMetaData structure!");this._metadata&&l.default.w(this.TAG,"Found another onMetaData tag!"),this._metadata=i;var r=this._metadata.onMetaData;if("boolean"==typeof r.hasAudio&&!1===this._hasAudioFlagOverrided&&(this._hasAudio=r.hasAudio,this._mediaInfo.hasAudio=this._hasAudio),"boolean"==typeof r.hasVideo&&!1===this._hasVideoFlagOverrided&&(this._hasVideo=r.hasVideo,this._mediaInfo.hasVideo=this._hasVideo),"number"==typeof r.audiodatarate&&(this._mediaInfo.audioDataRate=r.audiodatarate),"number"==typeof r.videodatarate&&(this._mediaInfo.videoDataRate=r.videodatarate),"number"==typeof r.width&&(this._mediaInfo.width=r.width),"number"==typeof r.height&&(this._mediaInfo.height=r.height),"number"==typeof r.duration){if(!this._durationOverrided){var s=Math.floor(r.duration*this._timescale);this._duration=s,this._mediaInfo.duration=s}}else this._mediaInfo.duration=0;if("number"==typeof r.framerate){var o=Math.floor(1e3*r.framerate);if(o>0){var u=o/1e3;this._referenceFrameRate.fixed=!0,this._referenceFrameRate.fps=u,this._referenceFrameRate.fps_num=o,this._referenceFrameRate.fps_den=1e3,this._mediaInfo.fps=u}}if("object"===a(r.keyframes)){this._mediaInfo.hasKeyframesIndex=!0;var d=r.keyframes;this._mediaInfo.keyframesIndex=this._parseKeyframesIndex(d),r.keyframes=null}else this._mediaInfo.hasKeyframesIndex=!1;this._dispatch=!1,this._mediaInfo.metadata=r,l.default.v(this.TAG,"Parsed onMetaData"),this._mediaInfo.isComplete()&&this._onMediaInfo(this._mediaInfo)}}},{key:"_parseKeyframesIndex",value:function(e){for(var t=[],n=[],i=1;i>>4;if(2!==a&&10!==a)return void this._onError(m.default.CODEC_UNSUPPORTED,"Flv: Unsupported audio codec idx: "+a);var o=0,u=(12&s)>>>2;if(!(u>=0&&u<=4))return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid audio sample rate idx: "+u);o=this._flvSoundRateTable[u];var d=1&s,h=this._audioMetadata,f=this._audioTrack;if(h||(!1===this._hasAudio&&!1===this._hasAudioFlagOverrided&&(this._hasAudio=!0,this._mediaInfo.hasAudio=!0),h=this._audioMetadata={},h.type="audio",h.id=f.id,h.timescale=this._timescale,h.duration=this._duration,h.audioSampleRate=o,h.channelCount=0===d?1:2),10===a){var c=this._parseAACAudioData(e,t+1,n-1);if(void 0==c)return;if(0===c.packetType){h.config&&l.default.w(this.TAG,"Found another AudioSpecificConfig!");var _=c.data;h.audioSampleRate=_.samplingRate,h.channelCount=_.channelCount,h.codec=_.codec,h.originalCodec=_.originalCodec,h.config=_.config,h.refSampleDuration=1024/h.audioSampleRate*h.timescale,l.default.v(this.TAG,"Parsed AudioSpecificConfig"),this._isInitialMetadataDispatched()?this._dispatch&&(this._audioTrack.length||this._videoTrack.length)&&this._onDataAvailable(this._audioTrack,this._videoTrack):this._audioInitialMetadataDispatched=!0,this._dispatch=!1,this._onTrackMetadata("audio",h);var p=this._mediaInfo;p.audioCodec=h.originalCodec,p.audioSampleRate=h.audioSampleRate,p.audioChannelCount=h.channelCount,p.hasVideo?null!=p.videoCodec&&(p.mimeType='video/x-flv; codecs="'+p.videoCodec+","+p.audioCodec+'"'):p.mimeType='video/x-flv; codecs="'+p.audioCodec+'"',p.isComplete()&&this._onMediaInfo(p)}else if(1===c.packetType){var v=this._timestampBase+i,g={unit:c.data,dts:v,pts:v};f.samples.push(g),f.length+=c.data.length}else l.default.e(this.TAG,"Flv: Unsupported AAC data type "+c.packetType)}else if(2===a){if(!h.codec){var y=this._parseMP3AudioData(e,t+1,n-1,!0);if(void 0==y)return;h.audioSampleRate=y.samplingRate,h.channelCount=y.channelCount,h.codec=y.codec,h.originalCodec=y.originalCodec,h.refSampleDuration=1152/h.audioSampleRate*h.timescale,l.default.v(this.TAG,"Parsed MPEG Audio Frame Header"),this._audioInitialMetadataDispatched=!0,this._onTrackMetadata("audio",h);var E=this._mediaInfo;E.audioCodec=h.codec,E.audioSampleRate=h.audioSampleRate,E.audioChannelCount=h.channelCount,E.audioDataRate=y.bitRate,E.hasVideo?null!=E.videoCodec&&(E.mimeType='video/x-flv; codecs="'+E.videoCodec+","+E.audioCodec+'"'):E.mimeType='video/x-flv; codecs="'+E.audioCodec+'"',E.isComplete()&&this._onMediaInfo(E)}var b=this._parseMP3AudioData(e,t+1,n-1,!1);if(void 0==b)return;var S=this._timestampBase+i,k={unit:b,dts:S,pts:S};f.samples.push(k),f.length+=b.length}}}},{ +key:"_parseAACAudioData",value:function(e,t,n){if(n<=1)return void l.default.w(this.TAG,"Flv: Invalid AAC packet, missing AACPacketType or/and Data!");var i={},r=new Uint8Array(e,t,n);return i.packetType=r[0],0===r[0]?i.data=this._parseAACAudioSpecificConfig(e,t+1,n-1):i.data=r.subarray(1),i}},{key:"_parseAACAudioSpecificConfig",value:function(e,t,n){var i=new Uint8Array(e,t,n),r=null,s=0,a=0,o=0,u=null;if(s=a=i[0]>>>3,(o=(7&i[0])<<1|i[1]>>>7)<0||o>=this._mpegSamplingRates.length)return void this._onError(m.default.FORMAT_ERROR,"Flv: AAC invalid sampling frequency index!");var l=this._mpegSamplingRates[o],d=(120&i[1])>>>3;if(d<0||d>=8)return void this._onError(m.default.FORMAT_ERROR,"Flv: AAC invalid channel configuration");5===s&&(u=(7&i[1])<<1|i[2]>>>7,i[2]);var h=self.navigator.userAgent.toLowerCase();return-1!==h.indexOf("firefox")?o>=6?(s=5,r=new Array(4),u=o-3):(s=2,r=new Array(2),u=o):-1!==h.indexOf("android")?(s=2,r=new Array(2),u=o):(s=5,u=o,r=new Array(4),o>=6?u=o-3:1===d&&(s=2,r=new Array(2),u=o)),r[0]=s<<3,r[0]|=(15&o)>>>1,r[1]=(15&o)<<7,r[1]|=(15&d)<<3,5===s&&(r[1]|=(15&u)>>>1,r[2]=(1&u)<<7,r[2]|=8,r[3]=0),{config:r,samplingRate:l,channelCount:d,codec:"mp4a.40."+s,originalCodec:"mp4a.40."+a}}},{key:"_parseMP3AudioData",value:function(e,t,n,i){if(n<4)return void l.default.w(this.TAG,"Flv: Invalid MP3 packet, header missing!");var r=(this._littleEndian,new Uint8Array(e,t,n)),s=null;if(i){if(255!==r[0])return;var a=r[1]>>>3&3,o=(6&r[1])>>1,u=(240&r[2])>>>4,d=(12&r[2])>>>2,h=r[3]>>>6&3,f=3!==h?2:1,c=0,_=0;switch(a){case 0:c=this._mpegAudioV25SampleRateTable[d];break;case 2:c=this._mpegAudioV20SampleRateTable[d];break;case 3:c=this._mpegAudioV10SampleRateTable[d]}switch(o){case 1:34,u>>4,o=15&s;if(7!==o)return void this._onError(m.default.CODEC_UNSUPPORTED,"Flv: Unsupported codec in video frame: "+o);this._parseAVCVideoPacket(e,t+1,n-1,i,r,a)}}},{key:"_parseAVCVideoPacket",value:function(e,t,n,i,r,s){if(n<4)return void l.default.w(this.TAG,"Flv: Invalid AVC packet, missing AVCPacketType or/and CompositionTime");var a=this._littleEndian,o=new DataView(e,t,n),u=o.getUint8(0),d=16777215&o.getUint32(0,!a);if(0===u)this._parseAVCDecoderConfigurationRecord(e,t+4,n-4);else if(1===u)this._parseAVCVideoData(e,t+4,n-4,i,r,s,d);else if(2!==u)return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid video packet type "+u)}},{key:"_parseAVCDecoderConfigurationRecord",value:function(e,t,n){if(n<7)return void l.default.w(this.TAG,"Flv: Invalid AVCDecoderConfigurationRecord, lack of data!");var i=this._videoMetadata,r=this._videoTrack,s=this._littleEndian,a=new DataView(e,t,n);i?void 0!==i.avcc&&l.default.w(this.TAG,"Found another AVCDecoderConfigurationRecord!"):(!1===this._hasVideo&&!1===this._hasVideoFlagOverrided&&(this._hasVideo=!0,this._mediaInfo.hasVideo=!0),i=this._videoMetadata={},i.type="video",i.id=r.id,i.timescale=this._timescale,i.duration=this._duration);var o=a.getUint8(0),u=a.getUint8(1);a.getUint8(2),a.getUint8(3);if(1!==o||0===u)return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid AVCDecoderConfigurationRecord");if(this._naluLengthSize=1+(3&a.getUint8(4)),3!==this._naluLengthSize&&4!==this._naluLengthSize)return void this._onError(m.default.FORMAT_ERROR,"Flv: Strange NaluLengthSizeMinusOne: "+(this._naluLengthSize-1));var d=31&a.getUint8(5);if(0===d)return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid AVCDecoderConfigurationRecord: No SPS");d>1&&l.default.w(this.TAG,"Flv: Strange AVCDecoderConfigurationRecord: SPS Count = "+d);for(var h=6,f=0;f1&&l.default.w(this.TAG,"Flv: Strange AVCDecoderConfigurationRecord: PPS Count = "+w),h++;for(var R=0;R=n){l.default.w(this.TAG,"Malformed Nalu near timestamp "+_+", offset = "+f+", dataSize = "+n);break}var p=u.getUint32(f,!o);if(3===c&&(p>>>=8),p>n-c)return void l.default.w(this.TAG,"Malformed Nalus near timestamp "+_+", NaluSize > DataSize!");var v=31&u.getUint8(f+c);5===v&&(m=!0);var g=new Uint8Array(e,t+f,c+p),y={type:v,data:g};d.push(y),h+=g.byteLength,f+=c+p}if(d.length){var E=this._videoTrack,b={units:d,length:h,isKeyframe:m,dts:_,cts:a,pts:_+a};m&&(b.fileposition=r),E.samples.push(b),E.length+=h}}},{key:"onTrackMetadata",get:function(){return this._onTrackMetadata},set:function(e){this._onTrackMetadata=e}},{key:"onMediaInfo",get:function(){return this._onMediaInfo},set:function(e){this._onMediaInfo=e}},{key:"onError",get:function(){return this._onError},set:function(e){this._onError=e}},{key:"onDataAvailable",get:function(){return this._onDataAvailable},set:function(e){this._onDataAvailable=e}},{key:"timestampBase",get:function(){return this._timestampBase},set:function(e){this._timestampBase=e}},{key:"overridedDuration",get:function(){return this._duration},set:function(e){this._durationOverrided=!0,this._duration=e,this._mediaInfo.duration=e}},{key:"overridedHasAudio",set:function(e){this._hasAudioFlagOverrided=!0,this._hasAudio=e,this._mediaInfo.hasAudio=e}},{key:"overridedHasVideo",set:function(e){this._hasVideoFlagOverrided=!0,this._hasVideo=e,this._mediaInfo.hasVideo=e}}],[{key:"probe",value:function(e){var t=new Uint8Array(e),n={match:!1};if(70!==t[0]||76!==t[1]||86!==t[2]||1!==t[3])return n;var i=(4&t[4])>>>2!=0,r=0!=(1&t[4]),a=s(t,5);return a<9?n:{match:!0,consumed:a,dataOffset:a,hasAudioTrack:i,hasVideoTrack:r}}}]),e}();n.default=y},{"../core/media-info.js":7,"../utils/exception.js":40,"../utils/logger.js":41,"./amf-parser.js":15,"./demux-errors.js":16,"./sps-parser.js":19}],19:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=2&&3===t[s]&&0===t[s-1]&&0===t[s-2]||(i[r]=t[s],r++);return new Uint8Array(i.buffer,0,r)}},{key:"parseSPS",value:function(t){var n=e._ebsp2rbsp(t),i=new a.default(n);i.readByte();var r=i.readByte();i.readByte();var s=i.readByte();i.readUEG();var o=e.getProfileString(r),u=e.getLevelString(s),l=1,d=420,h=[0,420,422,444],f=8;if((100===r||110===r||122===r||244===r||44===r||83===r||86===r||118===r||128===r||138===r||144===r)&&(l=i.readUEG(),3===l&&i.readBits(1),l<=3&&(d=h[l]),f=i.readUEG()+8,i.readUEG(),i.readBits(1),i.readBool()))for(var c=3!==l?8:12,_=0;_0&&I<16?(w=x[I-1],R=M[I-1]):255===I&&(w=i.readByte()<<8|i.readByte(),R=i.readByte()<<8|i.readByte())}if(i.readBool()&&i.readBool(),i.readBool()&&(i.readBits(4),i.readBool()&&i.readBits(24)),i.readBool()&&(i.readUEG(),i.readUEG()),i.readBool()){var D=i.readBits(32),B=i.readBits(32);O=i.readBool(),T=B,C=2*D,A=T/C}}var j=1;1===w&&1===R||(j=w/R);var P=0,U=0;if(0===l)P=1,U=2-E;else{var N=3===l?1:2,F=1===l?2:1;P=N,U=F*(2-E)}var G=16*(g+1),V=16*(y+1)*(2-E);G-=(b+S)*P,V-=(k+L)*U;var z=Math.ceil(G*j);return i.destroy(),i=null,{profile_string:o,level_string:u,bit_depth:f,chroma_format:d,chroma_format_string:e.getChromaFormatString(d),frame_rate:{fixed:O,fps:A,fps_den:C,fps_num:T},sar_ratio:{width:w,height:R},codec_size:{width:G,height:V},present_size:{width:z,height:V}}}},{key:"_skipScalingList",value:function(e,t){for(var n=8,i=8,r=0,s=0;s=15048,t=!f.default.msedge||e;return self.fetch&&self.ReadableStream&&t}catch(e){return!1}}}]),l(t,[{key:"destroy",value:function(){this.isWorking()&&this.abort(),u(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"destroy",this).call(this)}},{key:"open",value:function(e,t){var n=this;this._dataSource=e,this._range=t;var i=e.url;this._config.reuseRedirectedURL&&void 0!=e.redirectedURL&&(i=e.redirectedURL);var r=this._seekHandler.getConfig(i,t),s=new self.Headers;if("object"===o(r.headers)){var a=r.headers;for(var u in a)a.hasOwnProperty(u)&&s.append(u,a[u])}var l={method:"GET",headers:s,mode:"cors",cache:"default",referrerPolicy:"no-referrer-when-downgrade"};!1===e.cors&&(l.mode="same-origin"),e.withCredentials&&(l.credentials="include"),e.referrerPolicy&&(l.referrerPolicy=e.referrerPolicy),this._status=c.LoaderStatus.kConnecting,self.fetch(r.url,l).then(function(e){if(n._requestAbort)return n._requestAbort=!1,void(n._status=c.LoaderStatus.kIdle);if(e.ok&&e.status>=200&&e.status<=299){if(e.url!==r.url&&n._onURLRedirect){var t=n._seekHandler.removeURLParameters(e.url);n._onURLRedirect(t)}var i=e.headers.get("Content-Length");return null!=i&&(n._contentLength=parseInt(i),0!==n._contentLength&&n._onContentLengthKnown&&n._onContentLengthKnown(n._contentLength)),n._pump.call(n,e.body.getReader())}if(n._status=c.LoaderStatus.kError,!n._onError)throw new _.RuntimeException("FetchStreamLoader: Http code invalid, "+e.status+" "+e.statusText);n._onError(c.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:e.status,msg:e.statusText})}).catch(function(e){if(n._status=c.LoaderStatus.kError,!n._onError)throw e;n._onError(c.LoaderErrors.EXCEPTION,{code:-1,msg:e.message})})}},{key:"abort",value:function(){this._requestAbort=!0}},{key:"_pump",value:function(e){var t=this;return e.read().then(function(n){if(n.done)t._status=c.LoaderStatus.kComplete,t._onComplete&&t._onComplete(t._range.from,t._range.from+t._receivedLength-1);else{if(!0===t._requestAbort)return t._requestAbort=!1,t._status=c.LoaderStatus.kComplete,e.cancel();t._status=c.LoaderStatus.kBuffering;var i=n.value.buffer,r=t._range.from+t._receivedLength;t._receivedLength+=i.byteLength,t._onDataArrival&&t._onDataArrival(i,r,t._receivedLength),t._pump(e)}}).catch(function(e){if(11!==e.code||!f.default.msedge){t._status=c.LoaderStatus.kError;var n=0,i=null;if(19!==e.code&&"network error"!==e.message||!(null===t._contentLength||null!==t._contentLength&&t._receivedLength0&&(this._stashInitialSize=n.stashInitialSize),this._stashUsed=0,this._stashSize=this._stashInitialSize,this._bufferSize=3145728,this._stashBuffer=new ArrayBuffer(this._bufferSize),this._stashByteStart=0,this._enableStash=!0,!1===n.enableStashBuffer&&(this._enableStash=!1),this._loader=null,this._loaderClass=null,this._seekHandler=null,this._dataSource=t,this._isWebSocketURL=/wss?:\/\/(.+?)/.test(t.url),this._refTotalLength=t.filesize?t.filesize:null,this._totalLength=this._refTotalLength,this._fullRequestFlag=!1,this._currentRange=null,this._redirectedURL=null,this._speedNormalized=0,this._speedSampler=new l.default,this._speedNormalizeList=[64,128,256,384,512,768,1024,1536,2048,3072,4096],this._isEarlyEofReconnecting=!1,this._paused=!1,this._resumeFrom=0,this._onDataArrival=null,this._onSeeked=null,this._onError=null,this._onComplete=null,this._onRedirect=null,this._onRecoveredEarlyEof=null,this._selectSeekHandler(),this._selectLoader(),this._createLoader()}return s(e,[{key:"destroy",value:function(){this._loader.isWorking()&&this._loader.abort(),this._loader.destroy(),this._loader=null,this._loaderClass=null,this._dataSource=null,this._stashBuffer=null,this._stashUsed=this._stashSize=this._bufferSize=this._stashByteStart=0,this._currentRange=null,this._speedSampler=null,this._isEarlyEofReconnecting=!1,this._onDataArrival=null,this._onSeeked=null,this._onError=null,this._onComplete=null,this._onRedirect=null,this._onRecoveredEarlyEof=null,this._extraData=null}},{key:"isWorking",value:function(){return this._loader&&this._loader.isWorking()&&!this._paused}},{key:"isPaused",value:function(){return this._paused}},{key:"_selectSeekHandler",value:function(){var e=this._config;if("range"===e.seekType)this._seekHandler=new b.default(this._config.rangeLoadZeroStart);else if("param"===e.seekType){var t=e.seekParamStart||"bstart",n=e.seekParamEnd||"bend";this._seekHandler=new k.default(t,n)}else{if("custom"!==e.seekType)throw new L.InvalidArgumentException("Invalid seekType in config: "+e.seekType);if("function"!=typeof e.customSeekHandler)throw new L.InvalidArgumentException("Custom seekType specified in config but invalid customSeekHandler!");this._seekHandler=new e.customSeekHandler}}},{key:"_selectLoader",value:function(){if(this._isWebSocketURL)this._loaderClass=y.default;else if(f.default.isSupported())this._loaderClass=f.default;else if(_.default.isSupported())this._loaderClass=_.default;else{if(!v.default.isSupported())throw new L.RuntimeException("Your browser doesn't support xhr with arraybuffer responseType!");this._loaderClass=v.default}}},{key:"_createLoader",value:function(){this._loader=new this._loaderClass(this._seekHandler,this._config),!1===this._loader.needStashBuffer&&(this._enableStash=!1),this._loader.onContentLengthKnown=this._onContentLengthKnown.bind(this),this._loader.onURLRedirect=this._onURLRedirect.bind(this),this._loader.onDataArrival=this._onLoaderChunkArrival.bind(this),this._loader.onComplete=this._onLoaderComplete.bind(this),this._loader.onError=this._onLoaderError.bind(this)}},{key:"open",value:function(e){this._currentRange={from:0,to:-1},e&&(this._currentRange.from=e),this._speedSampler.reset(),e||(this._fullRequestFlag=!0),this._loader.open(this._dataSource,Object.assign({},this._currentRange))}},{key:"abort",value:function(){this._loader.abort(),this._paused&&(this._paused=!1,this._resumeFrom=0)}},{key:"pause",value:function(){this.isWorking()&&(this._loader.abort(),0!==this._stashUsed?(this._resumeFrom=this._stashByteStart,this._currentRange.to=this._stashByteStart-1):this._resumeFrom=this._currentRange.to+1,this._stashUsed=0,this._stashByteStart=0,this._paused=!0)}},{key:"resume",value:function(){if(this._paused){this._paused=!1;var e=this._resumeFrom;this._resumeFrom=0,this._internalSeek(e,!0)}}},{key:"seek",value:function(e){this._paused=!1,this._stashUsed=0,this._stashByteStart=0,this._internalSeek(e,!0)}},{key:"_internalSeek",value:function(e,t){this._loader.isWorking()&&this._loader.abort(),this._flushStashBuffer(t),this._loader.destroy(),this._loader=null;var n={from:e,to:-1};this._currentRange={from:n.from,to:-1},this._speedSampler.reset(),this._stashSize=this._stashInitialSize,this._createLoader(),this._loader.open(this._dataSource,n),this._onSeeked&&this._onSeeked()}},{key:"updateUrl",value:function(e){if(!e||"string"!=typeof e||0===e.length)throw new L.InvalidArgumentException("Url must be a non-empty string!");this._dataSource.url=e}},{key:"_expandBuffer",value:function(e){for(var t=this._stashSize;t+10485760){var i=new Uint8Array(this._stashBuffer,0,this._stashUsed);new Uint8Array(n,0,t).set(i,0)}this._stashBuffer=n,this._bufferSize=t}}},{key:"_normalizeSpeed",value:function(e){var t=this._speedNormalizeList,n=t.length-1,i=0,r=0,s=n;if(e=t[i]&&e=512&&e<=1024?Math.floor(1.5*e):2*e)>8192&&(t=8192);var n=1024*t+1048576;this._bufferSize0){var o=this._stashBuffer.slice(0,this._stashUsed),u=this._dispatchChunks(o,this._stashByteStart);if(u0){var l=new Uint8Array(o,u);a.set(l,0),this._stashUsed=l.byteLength,this._stashByteStart+=u}}else this._stashUsed=0,this._stashByteStart+=u;this._stashUsed+e.byteLength>this._bufferSize&&(this._expandBuffer(this._stashUsed+e.byteLength),a=new Uint8Array(this._stashBuffer,0,this._bufferSize)),a.set(new Uint8Array(e),this._stashUsed),this._stashUsed+=e.byteLength}else{var d=this._dispatchChunks(e,t);if(dthis._bufferSize&&(this._expandBuffer(h),a=new Uint8Array(this._stashBuffer,0,this._bufferSize)),a.set(new Uint8Array(e,d),0),this._stashUsed+=h,this._stashByteStart=t+d}}}else if(0===this._stashUsed){var f=this._dispatchChunks(e,t);if(fthis._bufferSize&&this._expandBuffer(c);var _=new Uint8Array(this._stashBuffer,0,this._bufferSize);_.set(new Uint8Array(e,f),0),this._stashUsed+=c,this._stashByteStart=t+f}}else{this._stashUsed+e.byteLength>this._bufferSize&&this._expandBuffer(this._stashUsed+e.byteLength);var m=new Uint8Array(this._stashBuffer,0,this._bufferSize);m.set(new Uint8Array(e),this._stashUsed),this._stashUsed+=e.byteLength;var p=this._dispatchChunks(this._stashBuffer.slice(0,this._stashUsed),this._stashByteStart);if(p0){var v=new Uint8Array(this._stashBuffer,p);m.set(v,0)}this._stashUsed-=p,this._stashByteStart+=p}}}},{key:"_flushStashBuffer",value:function(e){if(this._stashUsed>0){var t=this._stashBuffer.slice(0,this._stashUsed),n=this._dispatchChunks(t,this._stashByteStart),i=t.byteLength-n;if(n0){var r=new Uint8Array(this._stashBuffer,0,this._bufferSize),s=new Uint8Array(t,n);r.set(s,0),this._stashUsed=s.byteLength,this._stashByteStart+=n}return 0}o.default.w(this.TAG,i+" bytes unconsumed data remain when flush buffer, dropped")}return this._stashUsed=0,this._stashByteStart=0,i}return 0}},{key:"_onLoaderComplete",value:function(e,t){this._flushStashBuffer(!0),this._onComplete&&this._onComplete(this._extraData)}},{key:"_onLoaderError",value:function(e,t){switch(o.default.e(this.TAG,"Loader error, code = "+t.code+", msg = "+t.msg),this._flushStashBuffer(!1),this._isEarlyEofReconnecting&&(this._isEarlyEofReconnecting=!1,e=d.LoaderErrors.UNRECOVERABLE_EARLY_EOF),e){case d.LoaderErrors.EARLY_EOF:if(!this._config.isLive&&this._totalLength){var n=this._currentRange.to+1;return void(n0)for(var s=n.split("&"),a=0;a0;o[0]!==this._startName&&o[0]!==this._endName&&(u&&(r+="&"),r+=s[a])}return 0===r.length?t:t+"?"+r}}]),e}();n.default=s},{}],26:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=500?this.currentKBps:0}},{key:"averageKBps",get:function(){var e=(this._now()-this._firstCheckpoint)/1e3;return this._totalBytes/e/1024}}]),e}();n.default=s},{}],28:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(n,"__esModule",{value:!0});var a=function e(t,n,i){null===t&&(t=Function.prototype);var r=Object.getOwnPropertyDescriptor(t,n);if(void 0===r){var s=Object.getPrototypeOf(t);return null===s?void 0:e(s,n,i)}if("value"in r)return r.value;var a=r.get;if(void 0!==a)return a.call(i)},o=function(){function e(e,t){for(var n=0;n299)){if(this._status=h.LoaderStatus.kError,!this._onError)throw new f.RuntimeException("MozChunkedLoader: Http code invalid, "+t.status+" "+t.statusText);this._onError(h.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:t.status,msg:t.statusText})}else this._status=h.LoaderStatus.kBuffering}}},{key:"_onProgress",value:function(e){if(this._status!==h.LoaderStatus.kError){null===this._contentLength&&null!==e.total&&0!==e.total&&(this._contentLength=e.total,this._onContentLengthKnown&&this._onContentLengthKnown(this._contentLength));var t=e.target.response,n=this._range.from+this._receivedLength;this._receivedLength+=t.byteLength,this._onDataArrival&&this._onDataArrival(t,n,this._receivedLength)}}},{key:"_onLoadEnd",value:function(e){if(!0===this._requestAbort)return void(this._requestAbort=!1);this._status!==h.LoaderStatus.kError&&(this._status=h.LoaderStatus.kComplete,this._onComplete&&this._onComplete(this._range.from,this._range.from+this._receivedLength-1))}},{key:"_onXhrError",value:function(e){this._status=h.LoaderStatus.kError;var t=0,n=null;if(this._contentLength&&e.loaded=200&&t.status<=299){if(this._status=h.LoaderStatus.kBuffering,void 0!=t.responseURL){var n=this._seekHandler.removeURLParameters(t.responseURL);t.responseURL!==this._currentRequestURL&&n!==this._currentRedirectedURL&&(this._currentRedirectedURL=n,this._onURLRedirect&&this._onURLRedirect(n))}var i=t.getResponseHeader("Content-Length");if(null!=i&&null==this._contentLength){var r=parseInt(i);r>0&&(this._contentLength=r,this._onContentLengthKnown&&this._onContentLengthKnown(this._contentLength))}}else{if(this._status=h.LoaderStatus.kError,!this._onError)throw new f.RuntimeException("MSStreamLoader: Http code invalid, "+t.status+" "+t.statusText);this._onError(h.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:t.status,msg:t.statusText})}else if(3===t.readyState&&t.status>=200&&t.status<=299){this._status=h.LoaderStatus.kBuffering;var s=t.response;this._reader.readAsArrayBuffer(s)}}},{key:"_xhrOnError",value:function(e){this._status=h.LoaderStatus.kError;var t=h.LoaderErrors.EXCEPTION,n={code:-1,msg:e.constructor.name+" "+e.type};if(!this._onError)throw new f.RuntimeException(n.msg);this._onError(t,n)}},{key:"_msrOnProgress",value:function(e){var t=e.target,n=t.result;if(null==n)return void this._doReconnectIfNeeded();var i=n.slice(this._lastTimeBufferSize);this._lastTimeBufferSize=n.byteLength;var r=this._totalRange.from+this._receivedLength;this._receivedLength+=i.byteLength,this._onDataArrival&&this._onDataArrival(i,r,this._receivedLength),n.byteLength>=this._bufferLimit&&(d.default.v(this.TAG,"MSStream buffer exceeded max size near "+(r+i.byteLength)+", reconnecting..."),this._doReconnectIfNeeded())}},{key:"_doReconnectIfNeeded",value:function(){if(null==this._contentLength||this._receivedLength=this._contentLength&&(n=this._range.from+this._contentLength-1),this._currentRequestRange={from:t,to:n},this._internalOpen(this._dataSource,this._currentRequestRange)}},{key:"_internalOpen",value:function(e,t){this._lastTimeLoaded=0;var n=e.url;this._config.reuseRedirectedURL&&(void 0!=this._currentRedirectedURL?n=this._currentRedirectedURL:void 0!=e.redirectedURL&&(n=e.redirectedURL));var i=this._seekHandler.getConfig(n,t);this._currentRequestURL=i.url;var r=this._xhr=new XMLHttpRequest;if(r.open("GET",i.url,!0),r.responseType="arraybuffer",r.onreadystatechange=this._onReadyStateChange.bind(this),r.onprogress=this._onProgress.bind(this),r.onload=this._onLoad.bind(this),r.onerror=this._onXhrError.bind(this),e.withCredentials&&r.withCredentials&&(r.withCredentials=!0),"object"===o(i.headers)){var s=i.headers;for(var a in s)s.hasOwnProperty(a)&&r.setRequestHeader(a,s[a])}r.send()}},{key:"abort",value:function(){this._requestAbort=!0,this._internalAbort(),this._status=_.LoaderStatus.kComplete}},{key:"_internalAbort",value:function(){this._xhr&&(this._xhr.onreadystatechange=null,this._xhr.onprogress=null,this._xhr.onload=null,this._xhr.onerror=null,this._xhr.abort(),this._xhr=null)}},{key:"_onReadyStateChange",value:function(e){var t=e.target;if(2===t.readyState){if(void 0!=t.responseURL){var n=this._seekHandler.removeURLParameters(t.responseURL);t.responseURL!==this._currentRequestURL&&n!==this._currentRedirectedURL&&(this._currentRedirectedURL=n,this._onURLRedirect&&this._onURLRedirect(n))}if(t.status>=200&&t.status<=299){if(this._waitForTotalLength)return;this._status=_.LoaderStatus.kBuffering}else{if(this._status=_.LoaderStatus.kError,!this._onError)throw new m.RuntimeException("RangeLoader: Http code invalid, "+t.status+" "+t.statusText);this._onError(_.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:t.status,msg:t.statusText})}}}},{key:"_onProgress",value:function(e){if(this._status!==_.LoaderStatus.kError){if(null===this._contentLength){var t=!1;if(this._waitForTotalLength){this._waitForTotalLength=!1,this._totalLengthReceived=!0,t=!0;var n=e.total;this._internalAbort(),null!=n&0!==n&&(this._totalLength=n)}if(-1===this._range.to?this._contentLength=this._totalLength-this._range.from:this._contentLength=this._range.to-this._range.from+1,t)return void this._openSubRange();this._onContentLengthKnown&&this._onContentLengthKnown(this._contentLength)}var i=e.loaded-this._lastTimeLoaded;this._lastTimeLoaded=e.loaded,this._speedSampler.addBytes(i)}}},{key:"_normalizeSpeed",value:function(e){var t=this._chunkSizeKBList,n=t.length-1,i=0,r=0,s=n;if(e=t[i]&&e=3&&(t=this._speedSampler.currentKBps),0!==t){var n=this._normalizeSpeed(t);this._currentSpeedNormalized!==n&&(this._currentSpeedNormalized=n,this._currentChunkSizeKB=n)}var i=e.target.response,r=this._range.from+this._receivedLength;this._receivedLength+=i.byteLength;var s=!1;null!=this._contentLength&&this._receivedLength0&&this._receivedLength0&&(this._requestSetTime=!0,this._mediaElement.currentTime=0),this._transmuxer=new p.default(this._mediaDataSource,this._config),this._transmuxer.on(g.default.INIT_SEGMENT,function(t,n){e._msectl.appendInitSegment(n)}),this._transmuxer.on(g.default.MEDIA_SEGMENT,function(t,n){if(e._msectl.appendMediaSegment(n),e._config.lazyLoad&&!e._config.isLive){var i=e._mediaElement.currentTime;n.info.endDts>=1e3*(i+e._config.lazyLoadMaxDuration)&&null==e._progressChecker&&(d.default.v(e.TAG,"Maximum buffering duration exceeded, suspend transmuxing task"),e._suspendTransmuxer())}}),this._transmuxer.on(g.default.LOADING_COMPLETE,function(){e._msectl.endOfStream(),e._emitter.emit(_.default.LOADING_COMPLETE)}),this._transmuxer.on(g.default.RECOVERED_EARLY_EOF,function(){e._emitter.emit(_.default.RECOVERED_EARLY_EOF)}),this._transmuxer.on(g.default.IO_ERROR,function(t,n){e._emitter.emit(_.default.ERROR,k.ErrorTypes.NETWORK_ERROR,t,n)}),this._transmuxer.on(g.default.DEMUX_ERROR,function(t,n){e._emitter.emit(_.default.ERROR,k.ErrorTypes.MEDIA_ERROR,t,{code:-1,msg:n})}), +this._transmuxer.on(g.default.MEDIA_INFO,function(t){e._mediaInfo=t,e._emitter.emit(_.default.MEDIA_INFO,Object.assign({},t))}),this._transmuxer.on(g.default.STATISTICS_INFO,function(t){e._statisticsInfo=e._fillStatisticsInfo(t),e._emitter.emit(_.default.STATISTICS_INFO,Object.assign({},e._statisticsInfo))}),this._transmuxer.on(g.default.RECOMMEND_SEEKPOINT,function(t){e._mediaElement&&!e._config.accurateSeek&&(e._requestSetTime=!0,e._mediaElement.currentTime=t/1e3)}),this._transmuxer.open()}}},{key:"unload",value:function(){this._mediaElement&&this._mediaElement.pause(),this._msectl&&this._msectl.seek(0),this._transmuxer&&(this._transmuxer.close(),this._transmuxer.destroy(),this._transmuxer=null)}},{key:"play",value:function(){return this._mediaElement.play()}},{key:"pause",value:function(){this._mediaElement.pause()}},{key:"_fillStatisticsInfo",value:function(e){if(e.playerType=this._type,!(this._mediaElement instanceof HTMLVideoElement))return e;var t=!0,n=0,i=0;if(this._mediaElement.getVideoPlaybackQuality){var r=this._mediaElement.getVideoPlaybackQuality();n=r.totalVideoFrames,i=r.droppedVideoFrames}else void 0!=this._mediaElement.webkitDecodedFrameCount?(n=this._mediaElement.webkitDecodedFrameCount,i=this._mediaElement.webkitDroppedFrameCount):t=!1;return t&&(e.decodedFrames=n,e.droppedFrames=i),e}},{key:"_onmseUpdateEnd",value:function(){if(this._config.lazyLoad&&!this._config.isLive){for(var e=this._mediaElement.buffered,t=this._mediaElement.currentTime,n=0,i=0;i=t+this._config.lazyLoadMaxDuration&&null==this._progressChecker&&(d.default.v(this.TAG,"Maximum buffering duration exceeded, suspend transmuxing task"),this._suspendTransmuxer())}}},{key:"_onmseBufferFull",value:function(){d.default.v(this.TAG,"MSE SourceBuffer is full, suspend transmuxing task"),null==this._progressChecker&&this._suspendTransmuxer()}},{key:"_suspendTransmuxer",value:function(){this._transmuxer&&(this._transmuxer.pause(),null==this._progressChecker&&(this._progressChecker=window.setInterval(this._checkProgressAndResume.bind(this),1e3)))}},{key:"_checkProgressAndResume",value:function(){for(var e=this._mediaElement.currentTime,t=this._mediaElement.buffered,n=!1,i=0;i=r&&e=s-this._config.lazyLoadRecoverDuration&&(n=!0);break}}n&&(window.clearInterval(this._progressChecker),this._progressChecker=null,n&&(d.default.v(this.TAG,"Continue loading from paused position"),this._transmuxer.resume()))}},{key:"_isTimepointBuffered",value:function(e){for(var t=this._mediaElement.buffered,n=0;n=i&&e0){var r=this._mediaElement.buffered.start(0);(r<1&&e0&&t.currentTime0){var i=n.start(0);if(i<1&&t0&&(this._mediaElement.currentTime=0),this._mediaElement.preload="auto",this._mediaElement.load(),this._statisticsReporter=window.setInterval(this._reportStatisticsInfo.bind(this),this._config.statisticsInfoReportInterval)}},{key:"unload",value:function(){this._mediaElement&&(this._mediaElement.src="",this._mediaElement.removeAttribute("src")),null!=this._statisticsReporter&&(window.clearInterval(this._statisticsReporter),this._statisticsReporter=null)}},{key:"play",value:function(){return this._mediaElement.play()}},{key:"pause",value:function(){this._mediaElement.pause()}},{key:"_onvLoadedMetadata",value:function(e){null!=this._pendingSeekTime&&(this._mediaElement.currentTime=this._pendingSeekTime,this._pendingSeekTime=null),this._emitter.emit(d.default.MEDIA_INFO,this.mediaInfo)}},{key:"_reportStatisticsInfo",value:function(){this._emitter.emit(d.default.STATISTICS_INFO,this.statisticsInfo)}},{key:"type",get:function(){return this._type}},{key:"buffered",get:function(){return this._mediaElement.buffered}},{key:"duration",get:function(){return this._mediaElement.duration}},{key:"volume",get:function(){return this._mediaElement.volume},set:function(e){this._mediaElement.volume=e}},{key:"muted",get:function(){return this._mediaElement.muted},set:function(e){this._mediaElement.muted=e}},{key:"currentTime",get:function(){return this._mediaElement?this._mediaElement.currentTime:0},set:function(e){this._mediaElement?this._mediaElement.currentTime=e:this._pendingSeekTime=e}},{key:"mediaInfo",get:function(){var e=this._mediaElement instanceof HTMLAudioElement?"audio/":"video/",t={mimeType:e+this._mediaDataSource.type};return this._mediaElement&&(t.duration=Math.floor(1e3*this._mediaElement.duration),this._mediaElement instanceof HTMLVideoElement&&(t.width=this._mediaElement.videoWidth,t.height=this._mediaElement.videoHeight)),t}},{key:"statisticsInfo",get:function(){var e={playerType:this._type,url:this._mediaDataSource.url};if(!(this._mediaElement instanceof HTMLVideoElement))return e;var t=!0,n=0,i=0;if(this._mediaElement.getVideoPlaybackQuality){var r=this._mediaElement.getVideoPlaybackQuality();n=r.totalVideoFrames,i=r.droppedVideoFrames}else void 0!=this._mediaElement.webkitDecodedFrameCount?(n=this._mediaElement.webkitDecodedFrameCount,i=this._mediaElement.webkitDroppedFrameCount):t=!1;return t&&(e.decodedFrames=n,e.droppedFrames=i),e}}]),e}();n.default=c},{"../config.js":5,"../utils/exception.js":40,"./player-events.js":35,events:2}],34:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.ErrorDetails=n.ErrorTypes=void 0;var i=e("../io/loader.js"),r=e("../demux/demux-errors.js"),s=function(e){return e&&e.__esModule?e:{default:e}}(r);n.ErrorTypes={NETWORK_ERROR:"NetworkError",MEDIA_ERROR:"MediaError",OTHER_ERROR:"OtherError"},n.ErrorDetails={NETWORK_EXCEPTION:i.LoaderErrors.EXCEPTION,NETWORK_STATUS_CODE_INVALID:i.LoaderErrors.HTTP_STATUS_CODE_INVALID,NETWORK_TIMEOUT:i.LoaderErrors.CONNECTING_TIMEOUT,NETWORK_UNRECOVERABLE_EARLY_EOF:i.LoaderErrors.UNRECOVERABLE_EARLY_EOF,MEDIA_MSE_ERROR:"MediaMSEError",MEDIA_FORMAT_ERROR:s.default.FORMAT_ERROR,MEDIA_FORMAT_UNSUPPORTED:s.default.FORMAT_UNSUPPORTED,MEDIA_CODEC_UNSUPPORTED:s.default.CODEC_UNSUPPORTED}},{"../demux/demux-errors.js":16,"../io/loader.js":24}],35:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i={ERROR:"error",LOADING_COMPLETE:"loading_complete",RECOVERED_EARLY_EOF:"recovered_early_eof",MEDIA_INFO:"media_info",STATISTICS_INFO:"statistics_info"};n.default=i},{}],36:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n>>24&255,n[1]=t>>>16&255,n[2]=t>>>8&255,n[3]=255&t,n.set(e,4);for(var a=8,o=0;o>>24&255,t>>>16&255,t>>>8&255,255&t,n>>>24&255,n>>>16&255,n>>>8&255,255&n,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]))}},{key:"trak",value:function(t){return e.box(e.types.trak,e.tkhd(t),e.mdia(t))}},{key:"tkhd",value:function(t){var n=t.id,i=t.duration,r=t.presentWidth,s=t.presentHeight;return e.box(e.types.tkhd,new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,0,0,0,0,i>>>24&255,i>>>16&255,i>>>8&255,255&i,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,r>>>8&255,255&r,0,0,s>>>8&255,255&s,0,0]))}},{key:"mdia",value:function(t){return e.box(e.types.mdia,e.mdhd(t),e.hdlr(t),e.minf(t))}},{key:"mdhd",value:function(t){var n=t.timescale,i=t.duration;return e.box(e.types.mdhd,new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,i>>>24&255,i>>>16&255,i>>>8&255,255&i,85,196,0,0]))}},{key:"hdlr",value:function(t){var n=null;return n="audio"===t.type?e.constants.HDLR_AUDIO:e.constants.HDLR_VIDEO,e.box(e.types.hdlr,n)}},{key:"minf",value:function(t){var n=null;return n="audio"===t.type?e.box(e.types.smhd,e.constants.SMHD):e.box(e.types.vmhd,e.constants.VMHD),e.box(e.types.minf,n,e.dinf(),e.stbl(t))}},{key:"dinf",value:function(){return e.box(e.types.dinf,e.box(e.types.dref,e.constants.DREF))}},{key:"stbl",value:function(t){return e.box(e.types.stbl,e.stsd(t),e.box(e.types.stts,e.constants.STTS),e.box(e.types.stsc,e.constants.STSC),e.box(e.types.stsz,e.constants.STSZ),e.box(e.types.stco,e.constants.STCO))}},{key:"stsd",value:function(t){return"audio"===t.type?"mp3"===t.codec?e.box(e.types.stsd,e.constants.STSD_PREFIX,e.mp3(t)):e.box(e.types.stsd,e.constants.STSD_PREFIX,e.mp4a(t)):e.box(e.types.stsd,e.constants.STSD_PREFIX,e.avc1(t))}},{key:"mp3",value:function(t){var n=t.channelCount,i=t.audioSampleRate,r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,n,0,16,0,0,0,0,i>>>8&255,255&i,0,0]);return e.box(e.types[".mp3"],r)}},{key:"mp4a",value:function(t){var n=t.channelCount,i=t.audioSampleRate,r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,n,0,16,0,0,0,0,i>>>8&255,255&i,0,0]);return e.box(e.types.mp4a,r,e.esds(t))}},{key:"esds",value:function(t){var n=t.config||[],i=n.length,r=new Uint8Array([0,0,0,0,3,23+i,0,1,0,4,15+i,64,21,0,0,0,0,0,0,0,0,0,0,0,5].concat([i]).concat(n).concat([6,1,2]));return e.box(e.types.esds,r)}},{key:"avc1",value:function(t){var n=t.avcc,i=t.codecWidth,r=t.codecHeight,s=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i>>>8&255,255&i,r>>>8&255,255&r,0,72,0,0,0,72,0,0,0,0,0,0,0,1,10,120,113,113,47,102,108,118,46,106,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,255,255]);return e.box(e.types.avc1,s,e.box(e.types.avcC,n))}},{key:"mvex",value:function(t){return e.box(e.types.mvex,e.trex(t))}},{key:"trex",value:function(t){var n=t.id,i=new Uint8Array([0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return e.box(e.types.trex,i)}},{key:"moof",value:function(t,n){return e.box(e.types.moof,e.mfhd(t.sequenceNumber),e.traf(t,n))}},{key:"mfhd",value:function(t){var n=new Uint8Array([0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,255&t]);return e.box(e.types.mfhd,n)}},{key:"traf",value:function(t,n){var i=t.id,r=e.box(e.types.tfhd,new Uint8Array([0,0,0,0,i>>>24&255,i>>>16&255,i>>>8&255,255&i])),s=e.box(e.types.tfdt,new Uint8Array([0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n])),a=e.sdtp(t),o=e.trun(t,a.byteLength+16+16+8+16+8+8);return e.box(e.types.traf,r,s,o,a)}},{key:"sdtp",value:function(t){for(var n=t.samples||[],i=n.length,r=new Uint8Array(4+i),s=0;s>>24&255,r>>>16&255,r>>>8&255,255&r,n>>>24&255,n>>>16&255,n>>>8&255,255&n],0);for(var o=0;o>>24&255,u>>>16&255,u>>>8&255,255&u,l>>>24&255,l>>>16&255,l>>>8&255,255&l,d.isLeading<<2|d.dependsOn,d.isDependedOn<<6|d.hasRedundancy<<4|d.isNonSync,0,0,h>>>24&255,h>>>16&255,h>>>8&255,255&h],12+16*o)}return e.box(e.types.trun,a)}},{key:"mdat",value:function(t){return e.box(e.types.mdat,t)}}]),e}();s.init(),n.default=s},{}],38:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n=1?A[A.length-1].duration:Math.floor(a);var D=!1,B=null;if(M>1.5*a&&"mp3"!==this._audioMeta.codec&&this._fillAudioTimestampGap&&!c.default.safari){D=!0;var j=Math.abs(M-a),P=Math.ceil(j/a),U=x+a;o.default.w(this.TAG,"Large audio timestamp gap detected, may cause AV sync to drift. Silent frames will be generated to avoid unsync.\ndts: "+(x+M)+" ms, expected: "+(x+Math.round(a))+" ms, delta: "+Math.round(j)+" ms, generate: "+P+" frames");var N=h.default.getSilentFrame(this._audioMeta.originalCodec,this._audioMeta.channelCount);null==N&&(o.default.w(this.TAG,"Unable to generate silent frame for "+this._audioMeta.originalCodec+" with "+this._audioMeta.channelCount+" channels, repeat last frame"),N=C),B=[];for(var F=0;F0){var V=B[B.length-1];V.duration=G-V.dts}var z={dts:G,pts:G,cts:0,unit:N,size:N.byteLength,duration:0,originalDts:I,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0}};B.push(z),v+=C.byteLength,U+=a}var H=B[B.length-1];H.duration=x+M-H.dts,M=Math.round(a)}A.push({dts:x,pts:x,cts:0,unit:T.unit,size:T.unit.byteLength,duration:M,originalDts:I,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0}}),D&&A.push.apply(A,B)}u?p=new Uint8Array(v):(p=new Uint8Array(v),p[0]=v>>>24&255,p[1]=v>>>16&255,p[2]=v>>>8&255,p[3]=255&v,p.set(l.default.types.mdat,4));for(var K=0;K>>24&255,h[1]=d>>>16&255,h[2]=d>>>8&255,h[3]=255&d,h.set(l.default.types.mdat,4);var f=n[0].dts-this._dtsBase;if(this._videoNextDts)i=f-this._videoNextDts;else if(this._videoSegmentInfoList.isEmpty())i=0;else{var c=this._videoSegmentInfoList.getLastSampleBefore(f);if(null!=c){var m=f-(c.originalDts+c.duration);m<=3&&(m=0);var p=c.dts+c.duration+m;i=f-p}else i=0}for(var v=new _.MediaSegmentInfo,g=[],y=0;y=1?g[g.length-1].duration:Math.floor(this._videoMeta.refSampleDuration);if(S){var A=new _.SampleInfo(k,w,R,E.dts,!0);A.fileposition=E.fileposition,v.appendSyncPoint(A)}g.push({dts:k,pts:w,cts:L,units:E.units,size:E.length,isKeyframe:S,duration:R,originalDts:b,flags:{isLeading:0,dependsOn:S?2:1,isDependedOn:S?1:0,hasRedundancy:0,isNonSync:S?0:1}})}for(var O=0;O=0&&/(rv)(?::| )([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(firefox)[ \/]([\w.]+)/.exec(e)||[],n=/(ipad)/.exec(e)||/(ipod)/.exec(e)||/(windows phone)/.exec(e)||/(iphone)/.exec(e)||/(kindle)/.exec(e)||/(android)/.exec(e)||/(windows)/.exec(e)||/(mac)/.exec(e)||/(linux)/.exec(e)||/(cros)/.exec(e)||[],r={browser:t[5]||t[3]||t[1]||"",version:t[2]||t[4]||"0",majorVersion:t[4]||t[2]||"0",platform:n[0]||""},s={};if(r.browser){s[r.browser]=!0;var a=r.majorVersion.split(".");s.version={major:parseInt(r.majorVersion,10),string:r.version},a.length>1&&(s.version.minor=parseInt(a[1],10)),a.length>2&&(s.version.build=parseInt(a[2],10))}r.platform&&(s[r.platform]=!0), +(s.chrome||s.opr||s.safari)&&(s.webkit=!0),(s.rv||s.iemobile)&&(s.rv&&delete s.rv,r.browser="msie",s.msie=!0),s.edge&&(delete s.edge,r.browser="msedge",s.msedge=!0),s.opr&&(r.browser="opera",s.opera=!0),s.safari&&s.android&&(r.browser="android",s.android=!0),s.name=r.browser,s.platform=r.platform;for(var o in i)i.hasOwnProperty(o)&&delete i[o];Object.assign(i,s)}(),n.default=i},{}],40:[function(e,t,n){"use strict";function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function r(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","error",i),e.ENABLE_ERROR&&(console.error?console.error(i):console.warn?console.warn(i):console.log(i))}},{key:"i",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","info",i),e.ENABLE_INFO&&(console.info?console.info(i):console.log(i))}},{key:"w",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","warn",i),e.ENABLE_WARN&&(console.warn?console.warn(i):console.log(i))}},{key:"d",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","debug",i),e.ENABLE_DEBUG&&(console.debug?console.debug(i):console.log(i))}},{key:"v",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","verbose",i),e.ENABLE_VERBOSE&&console.log(i)}}]),e}();o.GLOBAL_TAG="flv.js",o.FORCE_GLOBAL_TAG=!1,o.ENABLE_ERROR=!0,o.ENABLE_INFO=!0,o.ENABLE_WARN=!0,o.ENABLE_DEBUG=!0,o.ENABLE_VERBOSE=!0,o.ENABLE_CALLBACK=!1,o.emitter=new a.default,n.default=o},{events:2}],42:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0){var n=e.getConfig();t.emit("change",n)}}},{key:"registerListener",value:function(t){e.emitter.addListener("change",t)}},{key:"removeListener",value:function(t){e.emitter.removeListener("change",t)}},{key:"addLogListener",value:function(t){l.default.emitter.addListener("log",t),l.default.emitter.listenerCount("log")>0&&(l.default.ENABLE_CALLBACK=!0,e._notifyChange())}},{key:"removeLogListener",value:function(t){l.default.emitter.removeListener("log",t),0===l.default.emitter.listenerCount("log")&&(l.default.ENABLE_CALLBACK=!1,e._notifyChange())}},{key:"forceGlobalTag",get:function(){return l.default.FORCE_GLOBAL_TAG},set:function(t){l.default.FORCE_GLOBAL_TAG=t,e._notifyChange()}},{key:"globalTag",get:function(){return l.default.GLOBAL_TAG},set:function(t){l.default.GLOBAL_TAG=t,e._notifyChange()}},{key:"enableAll",get:function(){return l.default.ENABLE_VERBOSE&&l.default.ENABLE_DEBUG&&l.default.ENABLE_INFO&&l.default.ENABLE_WARN&&l.default.ENABLE_ERROR},set:function(t){l.default.ENABLE_VERBOSE=t,l.default.ENABLE_DEBUG=t,l.default.ENABLE_INFO=t,l.default.ENABLE_WARN=t,l.default.ENABLE_ERROR=t,e._notifyChange()}},{key:"enableDebug",get:function(){return l.default.ENABLE_DEBUG},set:function(t){l.default.ENABLE_DEBUG=t,e._notifyChange()}},{key:"enableVerbose",get:function(){return l.default.ENABLE_VERBOSE},set:function(t){l.default.ENABLE_VERBOSE=t,e._notifyChange()}},{key:"enableInfo",get:function(){return l.default.ENABLE_INFO},set:function(t){l.default.ENABLE_INFO=t,e._notifyChange()}},{key:"enableWarn",get:function(){return l.default.ENABLE_WARN},set:function(t){l.default.ENABLE_WARN=t,e._notifyChange()}},{key:"enableError",get:function(){return l.default.ENABLE_ERROR},set:function(t){l.default.ENABLE_ERROR=t,e._notifyChange()}}]),e}();d.emitter=new o.default,n.default=d},{"./logger.js":41,events:2}],43:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=128){t.push(String.fromCharCode(65535&a)),r+=2;continue}}}else if(n[r]<240){if(i(n,r,2)){var o=(15&n[r])<<12|(63&n[r+1])<<6|63&n[r+2];if(o>=2048&&55296!=(63488&o)){t.push(String.fromCharCode(65535&o)),r+=3;continue}}}else if(n[r]<248&&i(n,r,3)){var u=(7&n[r])<<18|(63&n[r+1])<<12|(63&n[r+2])<<6|63&n[r+3];if(u>65536&&u<1114112){u-=65536,t.push(String.fromCharCode(u>>>10|55296)),t.push(String.fromCharCode(1023&u|56320)),r+=4;continue}}t.push(String.fromCharCode(65533)),++r}return t.join("")}Object.defineProperty(n,"__esModule",{value:!0}),n.default=r},{}]},{},[21])(21)}); +//# sourceMappingURL=flv.min.js.map diff --git a/tools/FLV Stream/flv.min.js.map b/tools/FLV Stream/flv.min.js.map new file mode 100644 index 0000000..05e110e --- /dev/null +++ b/tools/FLV Stream/flv.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/es6-promise/dist/es6-promise.js","node_modules/events/events.js","node_modules/process/browser.js","node_modules/webworkify/index.js","src/config.js","src/core/features.js","src/core/media-info.js","src/core/media-segment-info.js","src/core/mse-controller.js","src/core/mse-events.js","src/core/transmuxer.js","src/core/transmuxing-controller.js","src/core/transmuxing-events.js","src/core/transmuxing-worker.js","src/demux/amf-parser.js","src/demux/demux-errors.js","src/demux/exp-golomb.js","src/demux/flv-demuxer.js","src/demux/sps-parser.js","src/flv.js","src/index.js","src/io/fetch-stream-loader.js","src/io/io-controller.js","src/io/loader.js","src/io/param-seek-handler.js","src/io/range-seek-handler.js","src/io/speed-sampler.js","src/io/websocket-loader.js","src/io/xhr-moz-chunked-loader.js","src/io/xhr-msstream-loader.js","src/io/xhr-range-loader.js","src/player/flv-player.js","src/player/native-player.js","src/player/player-errors.js","src/player/player-events.js","src/remux/aac-silent.js","src/remux/mp4-generator.js","src/remux/mp4-remuxer.js","src/utils/browser.js","src/utils/exception.js","src/utils/logger.js","src/utils/logging-control.js","src/utils/polyfill.js","src/utils/utf8-conv.js"],"names":["f","exports","module","define","amd","g","window","global","self","this","flvjs","e","t","n","r","s","o","u","a","require","i","Error","code","l","call","length","1","_dereq_","factory","ES6Promise","objectOrFunction","x","isFunction","setScheduler","scheduleFn","customSchedulerFn","setAsap","asapFn","asap","useVertxTimer","vertxNext","flush","useSetTimeout","globalSetTimeout","setTimeout","len","callback","queue","undefined","then","onFulfillment","onRejection","_arguments","arguments","parent","child","constructor","noop","PROMISE_ID","makePromise","_state","invokeCallback","_result","subscribe","resolve","object","Constructor","promise","_resolve","selfFulfillment","TypeError","cannotReturnOwn","getThen","error","GET_THEN_ERROR","tryThen","value","fulfillmentHandler","rejectionHandler","handleForeignThenable","thenable","sealed","fulfill","reason","_reject","_label","handleOwnThenable","FULFILLED","REJECTED","handleMaybeThenable","maybeThenable","then$$","publishRejection","_onerror","publish","PENDING","_subscribers","subscribers","settled","detail","ErrorObject","tryCatch","TRY_CATCH_ERROR","hasCallback","succeeded","failed","initializePromise","resolver","nextId","id","Enumerator","input","_instanceConstructor","isArray","_input","_remaining","Array","_enumerate","validationError","all","entries","race","reject","_","needsResolver","needsNew","Promise","polyfill","local","Function","P","promiseToString","Object","prototype","toString","cast","_isArray","arg","scheduleFlush","browserWindow","browserGlobal","BrowserMutationObserver","MutationObserver","WebKitMutationObserver","isNode","process","isWorker","Uint8ClampedArray","importScripts","MessageChannel","nextTick","iterations","observer","node","document","createTextNode","observe","characterData","data","channel","port1","onmessage","port2","postMessage","vertx","runOnLoop","runOnContext","Math","random","substring","_eachEntry","entry","c","resolve$$","_then","_settledAt","_willSettleAt","state","enumerator","_setScheduler","_setAsap","_asap","catch","EventEmitter","_events","_maxListeners","isNumber","isObject","isUndefined","defaultMaxListeners","setMaxListeners","isNaN","emit","type","er","handler","args","listeners","err","context","slice","apply","addListener","listener","m","newListener","push","warned","console","trace","on","once","removeListener","fired","list","position","splice","removeAllListeners","key","listenerCount","evlistener","emitter","defaultSetTimout","defaultClearTimeout","runTimeout","fun","cachedSetTimeout","runClearTimeout","marker","cachedClearTimeout","clearTimeout","cleanUpNextTick","draining","currentQueue","concat","queueIndex","drainQueue","timeout","run","Item","array","title","browser","env","argv","version","versions","off","prependListener","prependOnceListener","name","binding","cwd","chdir","dir","umask","bundleFn","sources","cache","stringify","JSON","fn","options","resolveSources","workerSources","depPath","depKey","wkey","cacheKeys","keys","exp","default","floor","pow","wcache","skey","scache","src","map","join","URL","webkitURL","mozURL","msURL","blob","Blob","bare","workerUrl","createObjectURL","worker","Worker","objectURL","createDefaultConfig","assign","defaultConfig","enableWorker","enableStashBuffer","stashInitialSize","isLive","lazyLoad","lazyLoadMaxDuration","lazyLoadRecoverDuration","deferLoadAfterSourceOpen","autoCleanupMaxBackwardDuration","autoCleanupMinBackwardDuration","statisticsInfoReportInterval","fixAudioTimestampGap","accurateSeek","seekType","seekParamStart","seekParamEnd","rangeLoadZeroStart","customSeekHandler","reuseRedirectedURL","_ioController","_config","Features","MediaSource","isTypeSupported","ioctl","_ioController2","loaderType","destroy","mimeType","videoElement","createElement","canPlay","canPlayType","features","mseFlvPlayback","mseLiveFlvPlayback","networkStreamIO","networkLoaderName","nativeMP4H264Playback","nativeWebmVP8Playback","nativeWebmVP9Playback","supportMSEH264Playback","supportNetworkStreamIO","getNetworkLoaderTypeName","supportNativeMediaPlayback","MediaInfo","_classCallCheck","duration","hasAudio","hasVideo","audioCodec","videoCodec","audioDataRate","videoDataRate","audioSampleRate","audioChannelCount","width","height","fps","profile","level","chromaFormat","sarNum","sarDen","metadata","segments","segmentCount","hasKeyframesIndex","keyframesIndex","audioInfoComplete","videoInfoComplete","milliseconds","table","keyframeIdx","_search","times","index","fileposition","filepositions","idx","last","mid","lbound","ubound","SampleInfo","dts","pts","originalDts","isSync","isSyncPoint","MediaSegmentInfo","beginDts","endDts","beginPts","endPts","originalBeginDts","originalEndDts","syncPoints","firstSample","lastSample","sampleInfo","IDRSampleList","_list","clear","MediaSegmentInfoList","_type","_lastAppendLocation","_searchNearestSegmentBefore","mediaSegmentInfo","msi","lastAppendIdx","insertIdx","segment","getLastSegmentBefore","segmentIdx","_logger","_browser","_mseEvents","_mediaSegmentInfo","_exception","MSEController","config","TAG","_emitter","_events2","autoCleanupSourceBuffer","onSourceOpen","_onSourceOpen","bind","onSourceEnded","_onSourceEnded","onSourceClose","_onSourceClose","onSourceBufferError","_onSourceBufferError","onSourceBufferUpdateEnd","_onSourceBufferUpdateEnd","_mediaSource","_mediaSourceObjectURL","_mediaElement","_isBufferFull","_hasPendingEos","_requireSetMediaDuration","_pendingMediaDuration","_pendingSourceBufferInit","_mimeTypes","video","audio","_sourceBuffers","_lastInitSegments","_pendingSegments","_pendingRemoveRanges","_idrList","detachMediaElement","event","mediaElement","IllegalStateException","ms","addEventListener","ps","sb","readyState","removeSourceBuffer","removeEventListener","endOfStream","_logger2","message","removeAttribute","revokeObjectURL","initSegment","deferred","is","container","codec","firstInitSegment","v","addSourceBuffer","_mseEvents2","ERROR","msg","updating","_doAppendSegments","_browser2","safari","mediaDuration","_updateMediaSourceDuration","mediaSegment","_needCleanupSourceBuffer","_doCleanupSourceBuffer","_hasPendingRemoveRanges","seconds","abort","buffered","start","end","_doRemoveRanges","lastInitSegment","_hasPendingSegments","getLastSyncPointBeforeDts","currentTime","doRemove","removeEnd","current","target","ranges","range","shift","remove","pendingSegments","timestampOffset","currentOffset","targetOffset","delta","abs","byteLength","appendBuffer","hasOwnProperty","appendArray","info","unshift","BUFFER_FULL","pendings","appendInitSegment","SOURCE_OPEN","prr","UPDATE_END","MSEEvents","_loggingControl","_transmuxingController","_transmuxingEvents","_transmuxingWorker","_mediaInfo","Transmuxer","mediaDataSource","work","_worker","_transmuxingWorker2","_workerDestroying","_onWorkerMessage","cmd","param","onLoggingConfigChanged","_onLoggingConfigChanged","_loggingControl2","registerListener","getConfig","_controller","_transmuxingController2","ctl","_transmuxingEvents2","IO_ERROR","_onIOError","DEMUX_ERROR","_onDemuxError","INIT_SEGMENT","_onInitSegment","MEDIA_SEGMENT","_onMediaSegment","LOADING_COMPLETE","_onLoadingComplete","RECOVERED_EARLY_EOF","_onRecoveredEarlyEof","MEDIA_INFO","_onMediaInfo","STATISTICS_INFO","_onStatisticsInfo","RECOMMEND_SEEKPOINT","_onRecommendSeekpoint","stop","seek","pause","resume","_this","_this2","_this3","_this4","mediaInfo","_this5","statisticsInfo","_this6","_this7","_this8","_this9","terminate","setPrototypeOf","_mediaInfo2","logcat","_flvDemuxer","_mp4Remuxer","_demuxErrors","TransmuxingController","filesize","url","cors","withCredentials","_mediaDataSource","_currentSegmentIndex","totalDuration","forEach","timestampBase","referrerPolicy","_demuxer","_remuxer","_ioctl","_pendingSeekTime","_pendingResolveSeekPoint","_statisticsReporter","_disableStatisticsReporter","_loadSegment","_enableStatisticsReporter","segmentIndex","optionalFrom","dataSource","onError","_onIOException","onSeeked","_onIOSeeked","onComplete","_onIOComplete","onRedirect","_onIORedirect","onRecoveredEarlyEof","_onIORecoveredEarlyEof","bindDataSource","onDataArrival","_onInitChunkArrival","open","_internalAbort","isWorking","isPaused","isSeekable","targetSegmentIndex","_searchSegmentIndexContains","segmentInfo","keyframe","getNearestKeyframe","targetSegmentInfo","insertDiscontinuity","_keyframe","resetMediaInfo","_reportSegmentMediaInfo","byteStart","probeData","consumed","parseChunks","_flvDemuxer2","probe","match","_mp4Remuxer2","mds","overridedDuration","overridedHasAudio","overridedHasVideo","_onDemuxException","onMediaInfo","onInitSegment","_onRemuxerInitSegmentArrival","onMediaSegment","_onRemuxerMediaSegmentArrival","_demuxErrors2","FORMAT_UNSUPPORTED","extraData","nextSegmentIndex","redirectedURL","seekpoint","setInterval","_reportStatisticsInfo","clearInterval","exportInfo","currentURL","hasRedirect","currentRedirectedURL","speed","currentSpeed","currentSegmentIndex","totalSegmentCount","TransmuxingEvents","_polyfill","TransmuxingWorker","obj","onLoadingComplete","onStatisticsInfo","statInfo","onIOError","onDemuxError","onRecommendSeekpoint","onLogcatCallback","str","controller","logcatListener","_polyfill2","install","applyConfig","enableCallback","addLogListener","removeLogListener","_utf8Conv","le","buf","ArrayBuffer","DataView","setInt16","Int16Array","AMF","arrayBuffer","dataOffset","dataSize","parseValue","size","parseString","isObjectEnd","objectEnd","parseObject","getUint16","_utf8Conv2","Uint8Array","getUint32","timestamp","getFloat64","getInt16","Date","offset","getUint8","amfstr","terminal","amfobj","_terminal","amfvar","parseVariable","strictArrayLength","val","date","parseDate","amfLongStr","w","DemuxErrors","OK","FORMAT_ERROR","CODEC_UNSUPPORTED","ExpGolomb","uint8array","_buffer","_buffer_index","_total_bytes","_total_bits","_current_word","_current_word_bits_left","buffer_bytes_left","bytes_read","min","word","set","subarray","buffer","bits","InvalidArgumentException","result","bits_need_left","_fillCurrentWord","bits_read_next","result2","readBits","zero_count","_skipLeadingZero","leading_zeros","readUEG","ReadBig32","_amfParser","_spsParser","FLVDemuxer","_onError","_onTrackMetadata","_onDataAvailable","_dataOffset","_firstParse","_dispatch","_hasAudio","hasAudioTrack","_hasVideo","hasVideoTrack","_hasAudioFlagOverrided","_hasVideoFlagOverrided","_audioInitialMetadataDispatched","_videoInitialMetadataDispatched","_metadata","_audioMetadata","_videoMetadata","_naluLengthSize","_timestampBase","_timescale","_duration","_durationOverrided","_referenceFrameRate","fixed","fps_num","fps_den","_flvSoundRateTable","_mpegSamplingRates","_mpegAudioV10SampleRateTable","_mpegAudioV20SampleRateTable","_mpegAudioV25SampleRateTable","_mpegAudioL1BitRateTable","_mpegAudioL2BitRateTable","_mpegAudioL3BitRateTable","_videoTrack","sequenceNumber","samples","_audioTrack","_littleEndian","loader","chunk","_v","tagType","ts2","ts1","ts0","ts3","_parseAudioData","_parseVideoData","_parseScriptData","prevTagSize","_isInitialMetadataDispatched","scriptData","_amfParser2","parseScriptData","onMetaData","_typeof","audiodatarate","videodatarate","framerate","keyframes","_parseKeyframesIndex","isComplete","time","tagTimestamp","soundSpec","soundFormat","soundRate","soundRateIndex","soundType","meta","track","timescale","channelCount","aacData","_parseAACAudioData","packetType","misc","samplingRate","originalCodec","refSampleDuration","mi","aacSample","unit","_misc","_parseMP3AudioData","_mi","bitRate","_dts","mp3Sample","_parseAACAudioSpecificConfig","audioObjectType","originalAudioObjectType","samplingIndex","extensionSamplingIndex","samplingFrequence","channelConfig","userAgent","navigator","toLowerCase","indexOf","requestHeader","ver","layer","bitrate_index","sampling_freq_index","channel_mode","channel_count","sample_rate","bit_rate","tagPosition","spec","frameType","codecId","_parseAVCVideoPacket","cts","_parseAVCDecoderConfigurationRecord","_parseAVCVideoData","avcc","avcProfile","spsCount","sps","_spsParser2","parseSPS","codecWidth","codec_size","codecHeight","presentWidth","present_size","presentHeight","profile_string","level_string","bitDepth","bit_depth","chroma_format","sarRatio","sar_ratio","frameRate","frame_rate","codecArray","codecString","j","h","chroma_format_string","ppsCount","_i","_len","units","lengthSize","naluSize","unitType","avcSample","isKeyframe","base","mismatch","_expGolomb","SPSParser","src_length","dst","dst_idx","rbsp","_ebsp2rbsp","gb","_expGolomb2","readByte","profile_idc","level_idc","getProfileString","getLevelString","chroma_format_idc","chroma_format_table","readBool","scaling_list_count","_skipScalingList","pic_order_cnt_type","readSEG","num_ref_frames_in_pic_order_cnt_cycle","pic_width_in_mbs_minus1","pic_height_in_map_units_minus1","frame_mbs_only_flag","frame_crop_left_offset","frame_crop_right_offset","frame_crop_top_offset","frame_crop_bottom_offset","sar_width","sar_height","fps_fixed","aspect_ratio_idc","sar_w_table","sar_h_table","num_units_in_tick","time_scale","sarScale","crop_unit_x","crop_unit_y","sub_wc","sub_hc","codec_width","codec_height","present_width","ceil","getChromaFormatString","count","last_scale","next_scale","delta_scale","toFixed","chroma","createPlayer","optionalConfig","_flvPlayer2","_nativePlayer2","isSupported","_features2","getFeatureList","_features","_flvPlayer","_nativePlayer","_playerEvents","_playerErrors","Events","_playerEvents2","ErrorTypes","ErrorDetails","FlvPlayer","NativePlayer","LoggingControl","defineProperty","enumerable","get","_loader","FetchStreamLoader","seekHandler","_possibleConstructorReturn","__proto__","getPrototypeOf","_seekHandler","_needStash","_requestAbort","_contentLength","_receivedLength","isWorkWellEdge","msedge","minor","browserNotBlacklisted","fetch","ReadableStream","_get","_dataSource","_range","sourceURL","seekConfig","headers","Headers","configHeaders","append","params","method","mode","credentials","_status","LoaderStatus","kConnecting","res","kIdle","ok","status","_onURLRedirect","removeURLParameters","lengthHeader","parseInt","_onContentLengthKnown","_pump","body","getReader","kError","RuntimeException","statusText","LoaderErrors","HTTP_STATUS_CODE_INVALID","EXCEPTION","reader","read","done","kComplete","_onComplete","from","cancel","kBuffering","_onDataArrival","EARLY_EOF","_speedSampler","_fetchStreamLoader","_xhrMozChunkedLoader","_xhrMsstreamLoader","_xhrRangeLoader","_websocketLoader","_rangeSeekHandler","_paramSeekHandler","IOController","_extraData","_stashInitialSize","_stashUsed","_stashSize","_bufferSize","_stashBuffer","_stashByteStart","_enableStash","_loaderClass","_isWebSocketURL","test","_refTotalLength","_totalLength","_fullRequestFlag","_currentRange","_redirectedURL","_speedNormalized","_speedSampler2","_speedNormalizeList","_isEarlyEofReconnecting","_paused","_resumeFrom","_onSeeked","_onRedirect","_selectSeekHandler","_selectLoader","_createLoader","_rangeSeekHandler2","paramStart","paramEnd","_paramSeekHandler2","_websocketLoader2","_fetchStreamLoader2","_xhrMozChunkedLoader2","_xhrRangeLoader2","needStashBuffer","onContentLengthKnown","onURLRedirect","_onLoaderChunkArrival","_onLoaderComplete","_onLoaderError","to","reset","bytes","_internalSeek","dropUnconsumed","_flushStashBuffer","requestRange","expectedBytes","bufferNewSize","newBuffer","stashOldArray","normalized","stashSizeKB","bufferSize","_expandBuffer","chunks","contentLength","receivedLength","addBytes","KBps","lastSecondKBps","_normalizeSpeed","_adjustStashSize","_stashArray2","_stashArray3","_consumed2","_dispatchChunks","_remainArray","_consumed3","_remain","remain","stashArray","_stashArray","_consumed","remainArray","UNRECOVERABLE_EARLY_EOF","nextFrom","CONNECTING_TIMEOUT","BaseLoader","typeName","NotImplementedException","ParamSeekHandler","_startName","_endName","baseUrl","needAnd","seekedURL","baseURL","split","queryIndex","resultParams","pairs","pair","requireAnd","RangeSeekHandler","zeroStart","_zeroStart","SpeedSampler","_firstCheckpoint","_lastCheckpoint","_intervalBytes","_totalBytes","_lastSecondBytes","performance","now","_now","durationSeconds","currentKBps","WebSocketLoader","_ws","WebSocket","ws","binaryType","onopen","_onWebSocketOpen","onclose","_onWebSocketClose","_onWebSocketMessage","onerror","_onWebSocketError","close","_dispatchArrayBuffer","FileReader","onload","readAsArrayBuffer","arraybuffer","MozChunkedLoader","_xhr","xhr","XMLHttpRequest","responseType","onreadystatechange","onprogress","onloadend","_requestURL","_onReadyStateChange","_onProgress","_onLoadEnd","_onXhrError","setRequestHeader","send","responseURL","total","response","loaded","MSStreamLoader","_reader","_totalRange","_currentRequestURL","_currentRedirectedURL","_bufferLimit","_lastTimeBufferSize","_isReconnecting","MSStream","MSStreamReader","_internalOpen","isSubrange","_msrOnProgress","_msrOnLoad","_msrOnError","_xhrOnReadyStateChange","_xhrOnError","getResponseHeader","msstream","bigbuffer","_doReconnectIfNeeded","RangeLoader","_chunkSizeKBList","_currentChunkSizeKB","_currentSpeedNormalized","_zeroSpeedChunkCount","_waitForTotalLength","_totalLengthReceived","_currentRequestRange","_lastTimeLoaded","useRefTotalLength","_openSubRange","chunkSize","_onLoad","openNextRange","reportComplete","_transmuxer","_mseController","onvLoadedMetadata","_onvLoadedMetadata","onvSeeking","_onvSeeking","onvCanPlay","_onvCanPlay","onvStalled","_onvStalled","onvProgress","_onvProgress","_requestSetTime","_seekpointRecord","_progressChecker","_msectl","_mseSourceOpened","_hasPendingLoad","_receivedCanPlay","_statisticsInfo","chromeNeedIDRFix","chrome","major","build","_alwaysSeekKeyframe","msie","unload","_mseController2","_onmseUpdateEnd","_onmseBufferFull","load","MEDIA_ERROR","MEDIA_MSE_ERROR","attachMediaElement","_transmuxer2","appendMediaSegment","_suspendTransmuxer","NETWORK_ERROR","_fillStatisticsInfo","play","playerType","HTMLVideoElement","hasQualityInfo","decoded","dropped","getVideoPlaybackQuality","quality","totalVideoFrames","droppedVideoFrames","webkitDecodedFrameCount","webkitDroppedFrameCount","decodedFrames","droppedFrames","currentRangeEnd","_checkProgressAndResume","needResume","directSeek","_isTimepointBuffered","directSeekBegin","directSeekBeginTime","videoBeginTime","idr","recordTime","_checkAndApplyUnbufferedSeekpoint","stalled","media","seekPoint","_checkAndResumeStuckPlayback","volume","muted","preload","mediaPrefix","HTMLAudioElement","videoWidth","videoHeight","OTHER_ERROR","NETWORK_EXCEPTION","NETWORK_STATUS_CODE_INVALID","NETWORK_TIMEOUT","NETWORK_UNRECOVERABLE_EARLY_EOF","MEDIA_FORMAT_ERROR","MEDIA_FORMAT_UNSUPPORTED","MEDIA_CODEC_UNSUPPORTED","PlayerEvents","AAC","MP4","types","avc1","avcC","btrt","dinf","dref","esds","ftyp","hdlr","mdat","mdhd","mdia","mfhd","minf","moof","moov","mp4a","mvex","mvhd","sdtp","stbl","stco","stsc","stsd","stsz","stts","tfdt","tfhd","traf","trak","trun","trex","tkhd","vmhd","smhd",".mp3","charCodeAt","constants","FTYP","STSD_PREFIX","STTS","STSC","STCO","STSZ","HDLR_VIDEO","HDLR_AUDIO","DREF","SMHD","VMHD","datas","arrayCount","box","trackId","xmhd","mp3","sampleRate","configSize","baseMediaDecodeTime","sampleCount","flags","isLeading","dependsOn","isDependedOn","hasRedundancy","isNonSync","init","_mp4Generator","_aacSilent","MP4Remuxer","_isLive","_dtsBase","_dtsBaseInited","_audioDtsBase","Infinity","_videoDtsBase","_audioNextDts","_videoNextDts","_audioMeta","_videoMeta","_audioSegmentInfoList","_videoSegmentInfoList","_forceFirstIDR","_fillSilentAfterSeek","_mp3UseMpegAudio","firefox","_fillAudioTimestampGap","producer","onDataAvailable","remux","onTrackMetadata","_onTrackMetadataReceived","audioTrack","videoTrack","_calculateDtsBase","_remuxVideo","_remuxAudio","metabox","_mp4Generator2","generateInitSegment","dtsCorrection","firstDts","lastDts","mpegRawTrack","firstSegmentAfterSeek","insertPrefixSilentFrame","mdatbox","mdatBytes","firstSampleOriginalDts","isEmpty","getLastSampleBefore","distance","expectedDts","firstSampleDts","videoSegment","silentUnit","_aacSilent2","getSilentFrame","silentFrameDuration","mp4Samples","sample","sampleDuration","needFillSilentFrames","silentFrames","frameCount","currentDts","round","_silentUnit","intDts","previousFrame","frame","lastFrame","_unit","latest","moofbox","_mergeBoxes","firstPts","lastPts","syncPoint","appendSyncPoint","_i2","Browser","ua","exec","platform_match","matched","majorVersion","platform","versionArray","string","opr","webkit","rv","iemobile","edge","android","_message","Log","tag","FORCE_GLOBAL_TAG","GLOBAL_TAG","ENABLE_CALLBACK","ENABLE_ERROR","warn","log","ENABLE_INFO","ENABLE_WARN","ENABLE_DEBUG","debug","ENABLE_VERBOSE","globalTag","forceGlobalTag","enableVerbose","enableDebug","enableInfo","enableWarn","enableError","_notifyChange","enable","Polyfill","proto","output","source","checkContinuation","checkLength","decodeUTF8","out","String","fromCharCode","ucs4","_ucs","_ucs2"],"mappings":"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","file":"flv.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o postsJSON\n values[1] // => commentsJSON\n\n return values;\n });\n ```\n\n @class Promise\n @param {function} resolver\n Useful for tooling.\n @constructor\n*/\nfunction Promise(resolver) {\n this[PROMISE_ID] = nextId();\n this._result = this._state = undefined;\n this._subscribers = [];\n\n if (noop !== resolver) {\n typeof resolver !== 'function' && needsResolver();\n this instanceof Promise ? initializePromise(this, resolver) : needsNew();\n }\n}\n\nPromise.all = all;\nPromise.race = race;\nPromise.resolve = resolve;\nPromise.reject = reject;\nPromise._setScheduler = setScheduler;\nPromise._setAsap = setAsap;\nPromise._asap = asap;\n\nPromise.prototype = {\n constructor: Promise,\n\n /**\n The primary way of interacting with a promise is through its `then` method,\n which registers callbacks to receive either a promise's eventual value or the\n reason why the promise cannot be fulfilled.\n \n ```js\n findUser().then(function(user){\n // user is available\n }, function(reason){\n // user is unavailable, and you are given the reason why\n });\n ```\n \n Chaining\n --------\n \n The return value of `then` is itself a promise. This second, 'downstream'\n promise is resolved with the return value of the first promise's fulfillment\n or rejection handler, or rejected if the handler throws an exception.\n \n ```js\n findUser().then(function (user) {\n return user.name;\n }, function (reason) {\n return 'default name';\n }).then(function (userName) {\n // If `findUser` fulfilled, `userName` will be the user's name, otherwise it\n // will be `'default name'`\n });\n \n findUser().then(function (user) {\n throw new Error('Found user, but still unhappy');\n }, function (reason) {\n throw new Error('`findUser` rejected and we're unhappy');\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.\n // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.\n });\n ```\n If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.\n \n ```js\n findUser().then(function (user) {\n throw new PedagogicalException('Upstream error');\n }).then(function (value) {\n // never reached\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // The `PedgagocialException` is propagated all the way down to here\n });\n ```\n \n Assimilation\n ------------\n \n Sometimes the value you want to propagate to a downstream promise can only be\n retrieved asynchronously. This can be achieved by returning a promise in the\n fulfillment or rejection handler. The downstream promise will then be pending\n until the returned promise is settled. This is called *assimilation*.\n \n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // The user's comments are now available\n });\n ```\n \n If the assimliated promise rejects, then the downstream promise will also reject.\n \n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // If `findCommentsByAuthor` fulfills, we'll have the value here\n }, function (reason) {\n // If `findCommentsByAuthor` rejects, we'll have the reason here\n });\n ```\n \n Simple Example\n --------------\n \n Synchronous Example\n \n ```javascript\n let result;\n \n try {\n result = findResult();\n // success\n } catch(reason) {\n // failure\n }\n ```\n \n Errback Example\n \n ```js\n findResult(function(result, err){\n if (err) {\n // failure\n } else {\n // success\n }\n });\n ```\n \n Promise Example;\n \n ```javascript\n findResult().then(function(result){\n // success\n }, function(reason){\n // failure\n });\n ```\n \n Advanced Example\n --------------\n \n Synchronous Example\n \n ```javascript\n let author, books;\n \n try {\n author = findAuthor();\n books = findBooksByAuthor(author);\n // success\n } catch(reason) {\n // failure\n }\n ```\n \n Errback Example\n \n ```js\n \n function foundBooks(books) {\n \n }\n \n function failure(reason) {\n \n }\n \n findAuthor(function(author, err){\n if (err) {\n failure(err);\n // failure\n } else {\n try {\n findBoooksByAuthor(author, function(books, err) {\n if (err) {\n failure(err);\n } else {\n try {\n foundBooks(books);\n } catch(reason) {\n failure(reason);\n }\n }\n });\n } catch(error) {\n failure(err);\n }\n // success\n }\n });\n ```\n \n Promise Example;\n \n ```javascript\n findAuthor().\n then(findBooksByAuthor).\n then(function(books){\n // found books\n }).catch(function(reason){\n // something went wrong\n });\n ```\n \n @method then\n @param {Function} onFulfilled\n @param {Function} onRejected\n Useful for tooling.\n @return {Promise}\n */\n then: then,\n\n /**\n `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same\n as the catch block of a try/catch statement.\n \n ```js\n function findAuthor(){\n throw new Error('couldn't find that author');\n }\n \n // synchronous\n try {\n findAuthor();\n } catch(reason) {\n // something went wrong\n }\n \n // async with promises\n findAuthor().catch(function(reason){\n // something went wrong\n });\n ```\n \n @method catch\n @param {Function} onRejection\n Useful for tooling.\n @return {Promise}\n */\n 'catch': function _catch(onRejection) {\n return this.then(null, onRejection);\n }\n};\n\nfunction polyfill() {\n var local = undefined;\n\n if (typeof global !== 'undefined') {\n local = global;\n } else if (typeof self !== 'undefined') {\n local = self;\n } else {\n try {\n local = Function('return this')();\n } catch (e) {\n throw new Error('polyfill failed because global object is unavailable in this environment');\n }\n }\n\n var P = local.Promise;\n\n if (P) {\n var promiseToString = null;\n try {\n promiseToString = Object.prototype.toString.call(P.resolve());\n } catch (e) {\n // silently ignored\n }\n\n if (promiseToString === '[object Promise]' && !P.cast) {\n return;\n }\n }\n\n local.Promise = Promise;\n}\n\n// Strange compat..\nPromise.polyfill = polyfill;\nPromise.Promise = Promise;\n\nreturn Promise;\n\n})));\n//# sourceMappingURL=es6-promise.map\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n args = Array.prototype.slice.call(arguments, 1);\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n args = Array.prototype.slice.call(arguments, 1);\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","var bundleFn = arguments[3];\nvar sources = arguments[4];\nvar cache = arguments[5];\n\nvar stringify = JSON.stringify;\n\nmodule.exports = function (fn, options) {\n var wkey;\n var cacheKeys = Object.keys(cache);\n\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n var exp = cache[key].exports;\n // Using babel as a transpiler to use esmodule, the export will always\n // be an object with the default export as a property of it. To ensure\n // the existing api and babel esmodule exports are both supported we\n // check for both\n if (exp === fn || exp && exp.default === fn) {\n wkey = key;\n break;\n }\n }\n\n if (!wkey) {\n wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n var wcache = {};\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n wcache[key] = key;\n }\n sources[wkey] = [\n Function(['require','module','exports'], '(' + fn + ')(self)'),\n wcache\n ];\n }\n var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n\n var scache = {}; scache[wkey] = wkey;\n sources[skey] = [\n Function(['require'], (\n // try to call default if defined to also support babel esmodule\n // exports\n 'var f = require(' + stringify(wkey) + ');' +\n '(f.default ? f.default : f)(self);'\n )),\n scache\n ];\n\n var workerSources = {};\n resolveSources(skey);\n\n function resolveSources(key) {\n workerSources[key] = true;\n\n for (var depPath in sources[key][1]) {\n var depKey = sources[key][1][depPath];\n if (!workerSources[depKey]) {\n resolveSources(depKey);\n }\n }\n }\n\n var src = '(' + bundleFn + ')({'\n + Object.keys(workerSources).map(function (key) {\n return stringify(key) + ':['\n + sources[key][0]\n + ',' + stringify(sources[key][1]) + ']'\n ;\n }).join(',')\n + '},{},[' + stringify(skey) + '])'\n ;\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n var blob = new Blob([src], { type: 'text/javascript' });\n if (options && options.bare) { return blob; }\n var workerUrl = URL.createObjectURL(blob);\n var worker = new Worker(workerUrl);\n worker.objectURL = workerUrl;\n return worker;\n};\n","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const defaultConfig = {\n enableWorker: false,\n enableStashBuffer: true,\n stashInitialSize: undefined,\n\n isLive: false,\n\n lazyLoad: true,\n lazyLoadMaxDuration: 3 * 60,\n lazyLoadRecoverDuration: 30,\n deferLoadAfterSourceOpen: true,\n\n // autoCleanupSourceBuffer: default as false, leave unspecified\n autoCleanupMaxBackwardDuration: 3 * 60,\n autoCleanupMinBackwardDuration: 2 * 60,\n\n statisticsInfoReportInterval: 600,\n\n fixAudioTimestampGap: true,\n\n accurateSeek: false,\n seekType: 'range', // [range, param, custom]\n seekParamStart: 'bstart',\n seekParamEnd: 'bend',\n rangeLoadZeroStart: false,\n customSeekHandler: undefined,\n reuseRedirectedURL: false\n // referrerPolicy: leave as unspecified\n};\n\nexport function createDefaultConfig() {\n return Object.assign({}, defaultConfig);\n}","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport IOController from '../io/io-controller.js';\nimport {createDefaultConfig} from '../config.js';\n\nclass Features {\n\n static supportMSEH264Playback() {\n return window.MediaSource &&\n window.MediaSource.isTypeSupported('video/mp4; codecs=\"avc1.42E01E,mp4a.40.2\"');\n }\n\n static supportNetworkStreamIO() {\n let ioctl = new IOController({}, createDefaultConfig());\n let loaderType = ioctl.loaderType;\n ioctl.destroy();\n return loaderType == 'fetch-stream-loader' || loaderType == 'xhr-moz-chunked-loader';\n }\n\n static getNetworkLoaderTypeName() {\n let ioctl = new IOController({}, createDefaultConfig());\n let loaderType = ioctl.loaderType;\n ioctl.destroy();\n return loaderType;\n }\n\n static supportNativeMediaPlayback(mimeType) {\n if (Features.videoElement == undefined) {\n Features.videoElement = window.document.createElement('video');\n }\n let canPlay = Features.videoElement.canPlayType(mimeType);\n return canPlay === 'probably' || canPlay == 'maybe';\n }\n\n static getFeatureList() {\n let features = {\n mseFlvPlayback: false,\n mseLiveFlvPlayback: false,\n networkStreamIO: false,\n networkLoaderName: '',\n nativeMP4H264Playback: false,\n nativeWebmVP8Playback: false,\n nativeWebmVP9Playback: false\n };\n\n features.mseFlvPlayback = Features.supportMSEH264Playback();\n features.networkStreamIO = Features.supportNetworkStreamIO();\n features.networkLoaderName = Features.getNetworkLoaderTypeName();\n features.mseLiveFlvPlayback = features.mseFlvPlayback && features.networkStreamIO;\n features.nativeMP4H264Playback = Features.supportNativeMediaPlayback('video/mp4; codecs=\"avc1.42001E, mp4a.40.2\"');\n features.nativeWebmVP8Playback = Features.supportNativeMediaPlayback('video/webm; codecs=\"vp8.0, vorbis\"');\n features.nativeWebmVP9Playback = Features.supportNativeMediaPlayback('video/webm; codecs=\"vp9\"');\n\n return features;\n }\n\n}\n\nexport default Features;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass MediaInfo {\n\n constructor() {\n this.mimeType = null;\n this.duration = null;\n\n this.hasAudio = null;\n this.hasVideo = null;\n this.audioCodec = null;\n this.videoCodec = null;\n this.audioDataRate = null;\n this.videoDataRate = null;\n\n this.audioSampleRate = null;\n this.audioChannelCount = null;\n\n this.width = null;\n this.height = null;\n this.fps = null;\n this.profile = null;\n this.level = null;\n this.chromaFormat = null;\n this.sarNum = null;\n this.sarDen = null;\n\n this.metadata = null;\n this.segments = null; // MediaInfo[]\n this.segmentCount = null;\n this.hasKeyframesIndex = null;\n this.keyframesIndex = null;\n }\n\n isComplete() {\n let audioInfoComplete = (this.hasAudio === false) ||\n (this.hasAudio === true &&\n this.audioCodec != null &&\n this.audioSampleRate != null &&\n this.audioChannelCount != null);\n\n let videoInfoComplete = (this.hasVideo === false) ||\n (this.hasVideo === true &&\n this.videoCodec != null &&\n this.width != null &&\n this.height != null &&\n this.fps != null &&\n this.profile != null &&\n this.level != null &&\n this.chromaFormat != null &&\n this.sarNum != null &&\n this.sarDen != null);\n\n // keyframesIndex may not be present\n return this.mimeType != null &&\n this.duration != null &&\n this.metadata != null &&\n this.hasKeyframesIndex != null &&\n audioInfoComplete &&\n videoInfoComplete;\n }\n\n isSeekable() {\n return this.hasKeyframesIndex === true;\n }\n\n getNearestKeyframe(milliseconds) {\n if (this.keyframesIndex == null) {\n return null;\n }\n\n let table = this.keyframesIndex;\n let keyframeIdx = this._search(table.times, milliseconds);\n\n return {\n index: keyframeIdx,\n milliseconds: table.times[keyframeIdx],\n fileposition: table.filepositions[keyframeIdx]\n };\n }\n\n _search(list, value) {\n let idx = 0;\n\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (value < list[0]) {\n idx = 0;\n lbound = ubound + 1; // skip search\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (value >= list[mid] && value < list[mid + 1])) {\n idx = mid;\n break;\n } else if (list[mid] < value) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n\n return idx;\n }\n\n}\n\nexport default MediaInfo;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Represents an media sample (audio / video)\nexport class SampleInfo {\n\n constructor(dts, pts, duration, originalDts, isSync) {\n this.dts = dts;\n this.pts = pts;\n this.duration = duration;\n this.originalDts = originalDts;\n this.isSyncPoint = isSync;\n this.fileposition = null;\n }\n\n}\n\n// Media Segment concept is defined in Media Source Extensions spec.\n// Particularly in ISO BMFF format, an Media Segment contains a moof box followed by a mdat box.\nexport class MediaSegmentInfo {\n\n constructor() {\n this.beginDts = 0;\n this.endDts = 0;\n this.beginPts = 0;\n this.endPts = 0;\n this.originalBeginDts = 0;\n this.originalEndDts = 0;\n this.syncPoints = []; // SampleInfo[n], for video IDR frames only\n this.firstSample = null; // SampleInfo\n this.lastSample = null; // SampleInfo\n }\n\n appendSyncPoint(sampleInfo) { // also called Random Access Point\n sampleInfo.isSyncPoint = true;\n this.syncPoints.push(sampleInfo);\n }\n\n}\n\n// Ordered list for recording video IDR frames, sorted by originalDts\nexport class IDRSampleList {\n\n constructor() {\n this._list = [];\n }\n\n clear() {\n this._list = [];\n }\n\n appendArray(syncPoints) {\n let list = this._list;\n\n if (syncPoints.length === 0) {\n return;\n }\n\n if (list.length > 0 && syncPoints[0].originalDts < list[list.length - 1].originalDts) {\n this.clear();\n }\n\n Array.prototype.push.apply(list, syncPoints);\n }\n\n getLastSyncPointBeforeDts(dts) {\n if (this._list.length == 0) {\n return null;\n }\n\n let list = this._list;\n let idx = 0;\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (dts < list[0].dts) {\n idx = 0;\n lbound = ubound + 1;\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (dts >= list[mid].dts && dts < list[mid + 1].dts)) {\n idx = mid;\n break;\n } else if (list[mid].dts < dts) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n return this._list[idx];\n }\n\n}\n\n// Data structure for recording information of media segments in single track.\nexport class MediaSegmentInfoList {\n\n constructor(type) {\n this._type = type;\n this._list = [];\n this._lastAppendLocation = -1; // cached last insert location\n }\n\n get type() {\n return this._type;\n }\n\n get length() {\n return this._list.length;\n }\n\n isEmpty() {\n return this._list.length === 0;\n }\n\n clear() {\n this._list = [];\n this._lastAppendLocation = -1;\n }\n\n _searchNearestSegmentBefore(originalBeginDts) {\n let list = this._list;\n if (list.length === 0) {\n return -2;\n }\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n let idx = 0;\n\n if (originalBeginDts < list[0].originalBeginDts) {\n idx = -1;\n return idx;\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (originalBeginDts > list[mid].lastSample.originalDts &&\n (originalBeginDts < list[mid + 1].originalBeginDts))) {\n idx = mid;\n break;\n } else if (list[mid].originalBeginDts < originalBeginDts) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n return idx;\n }\n\n _searchNearestSegmentAfter(originalBeginDts) {\n return this._searchNearestSegmentBefore(originalBeginDts) + 1;\n }\n\n append(mediaSegmentInfo) {\n let list = this._list;\n let msi = mediaSegmentInfo;\n let lastAppendIdx = this._lastAppendLocation;\n let insertIdx = 0;\n\n if (lastAppendIdx !== -1 && lastAppendIdx < list.length &&\n msi.originalBeginDts >= list[lastAppendIdx].lastSample.originalDts &&\n ((lastAppendIdx === list.length - 1) ||\n (lastAppendIdx < list.length - 1 &&\n msi.originalBeginDts < list[lastAppendIdx + 1].originalBeginDts))) {\n insertIdx = lastAppendIdx + 1; // use cached location idx\n } else {\n if (list.length > 0) {\n insertIdx = this._searchNearestSegmentBefore(msi.originalBeginDts) + 1;\n }\n }\n\n this._lastAppendLocation = insertIdx;\n this._list.splice(insertIdx, 0, msi);\n }\n\n getLastSegmentBefore(originalBeginDts) {\n let idx = this._searchNearestSegmentBefore(originalBeginDts);\n if (idx >= 0) {\n return this._list[idx];\n } else { // -1\n return null;\n }\n }\n\n getLastSampleBefore(originalBeginDts) {\n let segment = this.getLastSegmentBefore(originalBeginDts);\n if (segment != null) {\n return segment.lastSample;\n } else {\n return null;\n }\n }\n\n getLastSyncPointBefore(originalBeginDts) {\n let segmentIdx = this._searchNearestSegmentBefore(originalBeginDts);\n let syncPoints = this._list[segmentIdx].syncPoints;\n while (syncPoints.length === 0 && segmentIdx > 0) {\n segmentIdx--;\n syncPoints = this._list[segmentIdx].syncPoints;\n }\n if (syncPoints.length > 0) {\n return syncPoints[syncPoints.length - 1];\n } else {\n return null;\n }\n }\n\n}","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport MSEEvents from './mse-events.js';\nimport {SampleInfo, IDRSampleList} from './media-segment-info.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\n// Media Source Extensions controller\nclass MSEController {\n\n constructor(config) {\n this.TAG = 'MSEController';\n\n this._config = config;\n this._emitter = new EventEmitter();\n\n if (this._config.isLive && this._config.autoCleanupSourceBuffer == undefined) {\n // For live stream, do auto cleanup by default\n this._config.autoCleanupSourceBuffer = true;\n }\n\n this.e = {\n onSourceOpen: this._onSourceOpen.bind(this),\n onSourceEnded: this._onSourceEnded.bind(this),\n onSourceClose: this._onSourceClose.bind(this),\n onSourceBufferError: this._onSourceBufferError.bind(this),\n onSourceBufferUpdateEnd: this._onSourceBufferUpdateEnd.bind(this)\n };\n\n this._mediaSource = null;\n this._mediaSourceObjectURL = null;\n this._mediaElement = null;\n\n this._isBufferFull = false;\n this._hasPendingEos = false;\n\n this._requireSetMediaDuration = false;\n this._pendingMediaDuration = 0;\n\n this._pendingSourceBufferInit = [];\n this._mimeTypes = {\n video: null,\n audio: null\n };\n this._sourceBuffers = {\n video: null,\n audio: null\n };\n this._lastInitSegments = {\n video: null,\n audio: null\n };\n this._pendingSegments = {\n video: [],\n audio: []\n };\n this._pendingRemoveRanges = {\n video: [],\n audio: []\n };\n this._idrList = new IDRSampleList();\n }\n\n destroy() {\n if (this._mediaElement || this._mediaSource) {\n this.detachMediaElement();\n }\n this.e = null;\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n attachMediaElement(mediaElement) {\n if (this._mediaSource) {\n throw new IllegalStateException('MediaSource has been attached to an HTMLMediaElement!');\n }\n let ms = this._mediaSource = new window.MediaSource();\n ms.addEventListener('sourceopen', this.e.onSourceOpen);\n ms.addEventListener('sourceended', this.e.onSourceEnded);\n ms.addEventListener('sourceclose', this.e.onSourceClose);\n\n this._mediaElement = mediaElement;\n this._mediaSourceObjectURL = window.URL.createObjectURL(this._mediaSource);\n mediaElement.src = this._mediaSourceObjectURL;\n }\n\n detachMediaElement() {\n if (this._mediaSource) {\n let ms = this._mediaSource;\n for (let type in this._sourceBuffers) {\n // pending segments should be discard\n let ps = this._pendingSegments[type];\n ps.splice(0, ps.length);\n this._pendingSegments[type] = null;\n this._pendingRemoveRanges[type] = null;\n this._lastInitSegments[type] = null;\n\n // remove all sourcebuffers\n let sb = this._sourceBuffers[type];\n if (sb) {\n if (ms.readyState !== 'closed') {\n ms.removeSourceBuffer(sb);\n sb.removeEventListener('error', this.e.onSourceBufferError);\n sb.removeEventListener('updateend', this.e.onSourceBufferUpdateEnd);\n }\n this._mimeTypes[type] = null;\n this._sourceBuffers[type] = null;\n }\n }\n if (ms.readyState === 'open') {\n try {\n ms.endOfStream();\n } catch (error) {\n Log.e(this.TAG, error.message);\n }\n }\n ms.removeEventListener('sourceopen', this.e.onSourceOpen);\n ms.removeEventListener('sourceended', this.e.onSourceEnded);\n ms.removeEventListener('sourceclose', this.e.onSourceClose);\n this._pendingSourceBufferInit = [];\n this._isBufferFull = false;\n this._idrList.clear();\n this._mediaSource = null;\n }\n\n if (this._mediaElement) {\n this._mediaElement.src = '';\n this._mediaElement.removeAttribute('src');\n this._mediaElement = null;\n }\n if (this._mediaSourceObjectURL) {\n window.URL.revokeObjectURL(this._mediaSourceObjectURL);\n this._mediaSourceObjectURL = null;\n }\n }\n\n appendInitSegment(initSegment, deferred) {\n if (!this._mediaSource || this._mediaSource.readyState !== 'open') {\n // sourcebuffer creation requires mediaSource.readyState === 'open'\n // so we defer the sourcebuffer creation, until sourceopen event triggered\n this._pendingSourceBufferInit.push(initSegment);\n // make sure that this InitSegment is in the front of pending segments queue\n this._pendingSegments[initSegment.type].push(initSegment);\n return;\n }\n\n let is = initSegment;\n let mimeType = `${is.container}`;\n if (is.codec && is.codec.length > 0) {\n mimeType += `;codecs=${is.codec}`;\n }\n\n let firstInitSegment = false;\n\n Log.v(this.TAG, 'Received Initialization Segment, mimeType: ' + mimeType);\n this._lastInitSegments[is.type] = is;\n\n if (mimeType !== this._mimeTypes[is.type]) {\n if (!this._mimeTypes[is.type]) { // empty, first chance create sourcebuffer\n firstInitSegment = true;\n try {\n let sb = this._sourceBuffers[is.type] = this._mediaSource.addSourceBuffer(mimeType);\n sb.addEventListener('error', this.e.onSourceBufferError);\n sb.addEventListener('updateend', this.e.onSourceBufferUpdateEnd);\n } catch (error) {\n Log.e(this.TAG, error.message);\n this._emitter.emit(MSEEvents.ERROR, {code: error.code, msg: error.message});\n return;\n }\n } else {\n Log.v(this.TAG, `Notice: ${is.type} mimeType changed, origin: ${this._mimeTypes[is.type]}, target: ${mimeType}`);\n }\n this._mimeTypes[is.type] = mimeType;\n }\n\n if (!deferred) {\n // deferred means this InitSegment has been pushed to pendingSegments queue\n this._pendingSegments[is.type].push(is);\n }\n if (!firstInitSegment) { // append immediately only if init segment in subsequence\n if (this._sourceBuffers[is.type] && !this._sourceBuffers[is.type].updating) {\n this._doAppendSegments();\n }\n }\n if (Browser.safari && is.container === 'audio/mpeg' && is.mediaDuration > 0) {\n // 'audio/mpeg' track under Safari may cause MediaElement's duration to be NaN\n // Manually correct MediaSource.duration to make progress bar seekable, and report right duration\n this._requireSetMediaDuration = true;\n this._pendingMediaDuration = is.mediaDuration / 1000; // in seconds\n this._updateMediaSourceDuration();\n }\n }\n\n appendMediaSegment(mediaSegment) {\n let ms = mediaSegment;\n this._pendingSegments[ms.type].push(ms);\n\n if (this._config.autoCleanupSourceBuffer && this._needCleanupSourceBuffer()) {\n this._doCleanupSourceBuffer();\n }\n\n let sb = this._sourceBuffers[ms.type];\n if (sb && !sb.updating && !this._hasPendingRemoveRanges()) {\n this._doAppendSegments();\n }\n }\n\n seek(seconds) {\n // remove all appended buffers\n for (let type in this._sourceBuffers) {\n if (!this._sourceBuffers[type]) {\n continue;\n }\n\n // abort current buffer append algorithm\n let sb = this._sourceBuffers[type];\n if (this._mediaSource.readyState === 'open') {\n try {\n // If range removal algorithm is running, InvalidStateError will be throwed\n // Ignore it.\n sb.abort();\n } catch (error) {\n Log.e(this.TAG, error.message);\n }\n }\n\n // IDRList should be clear\n this._idrList.clear();\n\n // pending segments should be discard\n let ps = this._pendingSegments[type];\n ps.splice(0, ps.length);\n\n if (this._mediaSource.readyState === 'closed') {\n // Parent MediaSource object has been detached from HTMLMediaElement\n continue;\n }\n\n // record ranges to be remove from SourceBuffer\n for (let i = 0; i < sb.buffered.length; i++) {\n let start = sb.buffered.start(i);\n let end = sb.buffered.end(i);\n this._pendingRemoveRanges[type].push({start, end});\n }\n\n // if sb is not updating, let's remove ranges now!\n if (!sb.updating) {\n this._doRemoveRanges();\n }\n\n // Safari 10 may get InvalidStateError in the later appendBuffer() after SourceBuffer.remove() call\n // Internal parser's state may be invalid at this time. Re-append last InitSegment to workaround.\n // Related issue: https://bugs.webkit.org/show_bug.cgi?id=159230\n if (Browser.safari) {\n let lastInitSegment = this._lastInitSegments[type];\n if (lastInitSegment) {\n this._pendingSegments[type].push(lastInitSegment);\n if (!sb.updating) {\n this._doAppendSegments();\n }\n }\n }\n }\n }\n\n endOfStream() {\n let ms = this._mediaSource;\n let sb = this._sourceBuffers;\n if (!ms || ms.readyState !== 'open') {\n if (ms && ms.readyState === 'closed' && this._hasPendingSegments()) {\n // If MediaSource hasn't turned into open state, and there're pending segments\n // Mark pending endOfStream, defer call until all pending segments appended complete\n this._hasPendingEos = true;\n }\n return;\n }\n if (sb.video && sb.video.updating || sb.audio && sb.audio.updating) {\n // If any sourcebuffer is updating, defer endOfStream operation\n // See _onSourceBufferUpdateEnd()\n this._hasPendingEos = true;\n } else {\n this._hasPendingEos = false;\n // Notify media data loading complete\n // This is helpful for correcting total duration to match last media segment\n // Otherwise MediaElement's ended event may not be triggered\n ms.endOfStream();\n }\n }\n\n getNearestKeyframe(dts) {\n return this._idrList.getLastSyncPointBeforeDts(dts);\n }\n\n _needCleanupSourceBuffer() {\n if (!this._config.autoCleanupSourceBuffer) {\n return false;\n }\n\n let currentTime = this._mediaElement.currentTime;\n\n for (let type in this._sourceBuffers) {\n let sb = this._sourceBuffers[type];\n if (sb) {\n let buffered = sb.buffered;\n if (buffered.length >= 1) {\n if (currentTime - buffered.start(0) >= this._config.autoCleanupMaxBackwardDuration) {\n return true;\n }\n }\n }\n }\n\n return false;\n }\n\n _doCleanupSourceBuffer() {\n let currentTime = this._mediaElement.currentTime;\n\n for (let type in this._sourceBuffers) {\n let sb = this._sourceBuffers[type];\n if (sb) {\n let buffered = sb.buffered;\n let doRemove = false;\n\n for (let i = 0; i < buffered.length; i++) {\n let start = buffered.start(i);\n let end = buffered.end(i);\n\n if (start <= currentTime && currentTime < end + 3) { // padding 3 seconds\n if (currentTime - start >= this._config.autoCleanupMaxBackwardDuration) {\n doRemove = true;\n let removeEnd = currentTime - this._config.autoCleanupMinBackwardDuration;\n this._pendingRemoveRanges[type].push({start: start, end: removeEnd});\n }\n } else if (end < currentTime) {\n doRemove = true;\n this._pendingRemoveRanges[type].push({start: start, end: end});\n }\n }\n\n if (doRemove && !sb.updating) {\n this._doRemoveRanges();\n }\n }\n }\n }\n\n _updateMediaSourceDuration() {\n let sb = this._sourceBuffers;\n if (this._mediaElement.readyState === 0 || this._mediaSource.readyState !== 'open') {\n return;\n }\n if ((sb.video && sb.video.updating) || (sb.audio && sb.audio.updating)) {\n return;\n }\n\n let current = this._mediaSource.duration;\n let target = this._pendingMediaDuration;\n\n if (target > 0 && (isNaN(current) || target > current)) {\n Log.v(this.TAG, `Update MediaSource duration from ${current} to ${target}`);\n this._mediaSource.duration = target;\n }\n\n this._requireSetMediaDuration = false;\n this._pendingMediaDuration = 0;\n }\n\n _doRemoveRanges() {\n for (let type in this._pendingRemoveRanges) {\n if (!this._sourceBuffers[type] || this._sourceBuffers[type].updating) {\n continue;\n }\n let sb = this._sourceBuffers[type];\n let ranges = this._pendingRemoveRanges[type];\n while (ranges.length && !sb.updating) {\n let range = ranges.shift();\n sb.remove(range.start, range.end);\n }\n }\n }\n\n _doAppendSegments() {\n let pendingSegments = this._pendingSegments;\n\n for (let type in pendingSegments) {\n if (!this._sourceBuffers[type] || this._sourceBuffers[type].updating) {\n continue;\n }\n\n if (pendingSegments[type].length > 0) {\n let segment = pendingSegments[type].shift();\n\n if (segment.timestampOffset) {\n // For MPEG audio stream in MSE, if unbuffered-seeking occurred\n // We need explicitly set timestampOffset to the desired point in timeline for mpeg SourceBuffer.\n let currentOffset = this._sourceBuffers[type].timestampOffset;\n let targetOffset = segment.timestampOffset / 1000; // in seconds\n\n let delta = Math.abs(currentOffset - targetOffset);\n if (delta > 0.1) { // If time delta > 100ms\n Log.v(this.TAG, `Update MPEG audio timestampOffset from ${currentOffset} to ${targetOffset}`);\n this._sourceBuffers[type].timestampOffset = targetOffset;\n }\n delete segment.timestampOffset;\n }\n\n if (!segment.data || segment.data.byteLength === 0) {\n // Ignore empty buffer\n continue;\n }\n\n try {\n this._sourceBuffers[type].appendBuffer(segment.data);\n this._isBufferFull = false;\n if (type === 'video' && segment.hasOwnProperty('info')) {\n this._idrList.appendArray(segment.info.syncPoints);\n }\n } catch (error) {\n this._pendingSegments[type].unshift(segment);\n if (error.code === 22) { // QuotaExceededError\n /* Notice that FireFox may not throw QuotaExceededError if SourceBuffer is full\n * Currently we can only do lazy-load to avoid SourceBuffer become scattered.\n * SourceBuffer eviction policy may be changed in future version of FireFox.\n *\n * Related issues:\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1279885\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1280023\n */\n\n // report buffer full, abort network IO\n if (!this._isBufferFull) {\n this._emitter.emit(MSEEvents.BUFFER_FULL);\n }\n this._isBufferFull = true;\n } else {\n Log.e(this.TAG, error.message);\n this._emitter.emit(MSEEvents.ERROR, {code: error.code, msg: error.message});\n }\n }\n }\n }\n }\n\n _onSourceOpen() {\n Log.v(this.TAG, 'MediaSource onSourceOpen');\n this._mediaSource.removeEventListener('sourceopen', this.e.onSourceOpen);\n // deferred sourcebuffer creation / initialization\n if (this._pendingSourceBufferInit.length > 0) {\n let pendings = this._pendingSourceBufferInit;\n while (pendings.length) {\n let segment = pendings.shift();\n this.appendInitSegment(segment, true);\n }\n }\n // there may be some pending media segments, append them\n if (this._hasPendingSegments()) {\n this._doAppendSegments();\n }\n this._emitter.emit(MSEEvents.SOURCE_OPEN);\n }\n\n _onSourceEnded() {\n // fired on endOfStream\n Log.v(this.TAG, 'MediaSource onSourceEnded');\n }\n\n _onSourceClose() {\n // fired on detaching from media element\n Log.v(this.TAG, 'MediaSource onSourceClose');\n if (this._mediaSource && this.e != null) {\n this._mediaSource.removeEventListener('sourceopen', this.e.onSourceOpen);\n this._mediaSource.removeEventListener('sourceended', this.e.onSourceEnded);\n this._mediaSource.removeEventListener('sourceclose', this.e.onSourceClose);\n }\n }\n\n _hasPendingSegments() {\n let ps = this._pendingSegments;\n return ps.video.length > 0 || ps.audio.length > 0;\n }\n\n _hasPendingRemoveRanges() {\n let prr = this._pendingRemoveRanges;\n return prr.video.length > 0 || prr.audio.length > 0;\n }\n\n _onSourceBufferUpdateEnd() {\n if (this._requireSetMediaDuration) {\n this._updateMediaSourceDuration();\n } else if (this._hasPendingRemoveRanges()) {\n this._doRemoveRanges();\n } else if (this._hasPendingSegments()) {\n this._doAppendSegments();\n } else if (this._hasPendingEos) {\n this.endOfStream();\n }\n this._emitter.emit(MSEEvents.UPDATE_END);\n }\n\n _onSourceBufferError(e) {\n Log.e(this.TAG, `SourceBuffer Error: ${e}`);\n // this error might not always be fatal, just ignore it\n }\n\n}\n\nexport default MSEController;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst MSEEvents = {\n ERROR: 'error',\n SOURCE_OPEN: 'source_open',\n UPDATE_END: 'update_end',\n BUFFER_FULL: 'buffer_full'\n};\n\nexport default MSEEvents;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport LoggingControl from '../utils/logging-control.js';\nimport TransmuxingController from './transmuxing-controller.js';\nimport TransmuxingEvents from './transmuxing-events.js';\nimport TransmuxingWorker from './transmuxing-worker.js';\nimport MediaInfo from './media-info.js';\n\nclass Transmuxer {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'Transmuxer';\n this._emitter = new EventEmitter();\n\n if (config.enableWorker && typeof (Worker) !== 'undefined') {\n try {\n let work = require('webworkify');\n this._worker = work(TransmuxingWorker);\n this._workerDestroying = false;\n this._worker.addEventListener('message', this._onWorkerMessage.bind(this));\n this._worker.postMessage({cmd: 'init', param: [mediaDataSource, config]});\n this.e = {\n onLoggingConfigChanged: this._onLoggingConfigChanged.bind(this)\n };\n LoggingControl.registerListener(this.e.onLoggingConfigChanged);\n this._worker.postMessage({cmd: 'logging_config', param: LoggingControl.getConfig()});\n } catch (error) {\n Log.e(this.TAG, 'Error while initialize transmuxing worker, fallback to inline transmuxing');\n this._worker = null;\n this._controller = new TransmuxingController(mediaDataSource, config);\n }\n } else {\n this._controller = new TransmuxingController(mediaDataSource, config);\n }\n\n if (this._controller) {\n let ctl = this._controller;\n ctl.on(TransmuxingEvents.IO_ERROR, this._onIOError.bind(this));\n ctl.on(TransmuxingEvents.DEMUX_ERROR, this._onDemuxError.bind(this));\n ctl.on(TransmuxingEvents.INIT_SEGMENT, this._onInitSegment.bind(this));\n ctl.on(TransmuxingEvents.MEDIA_SEGMENT, this._onMediaSegment.bind(this));\n ctl.on(TransmuxingEvents.LOADING_COMPLETE, this._onLoadingComplete.bind(this));\n ctl.on(TransmuxingEvents.RECOVERED_EARLY_EOF, this._onRecoveredEarlyEof.bind(this));\n ctl.on(TransmuxingEvents.MEDIA_INFO, this._onMediaInfo.bind(this));\n ctl.on(TransmuxingEvents.STATISTICS_INFO, this._onStatisticsInfo.bind(this));\n ctl.on(TransmuxingEvents.RECOMMEND_SEEKPOINT, this._onRecommendSeekpoint.bind(this));\n }\n }\n\n destroy() {\n if (this._worker) {\n if (!this._workerDestroying) {\n this._workerDestroying = true;\n this._worker.postMessage({cmd: 'destroy'});\n LoggingControl.removeListener(this.e.onLoggingConfigChanged);\n this.e = null;\n }\n } else {\n this._controller.destroy();\n this._controller = null;\n }\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n hasWorker() {\n return this._worker != null;\n }\n\n open() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'start'});\n } else {\n this._controller.start();\n }\n }\n\n close() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'stop'});\n } else {\n this._controller.stop();\n }\n }\n\n seek(milliseconds) {\n if (this._worker) {\n this._worker.postMessage({cmd: 'seek', param: milliseconds});\n } else {\n this._controller.seek(milliseconds);\n }\n }\n\n pause() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'pause'});\n } else {\n this._controller.pause();\n }\n }\n\n resume() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'resume'});\n } else {\n this._controller.resume();\n }\n }\n\n _onInitSegment(type, initSegment) {\n // do async invoke\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.INIT_SEGMENT, type, initSegment);\n });\n }\n\n _onMediaSegment(type, mediaSegment) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.MEDIA_SEGMENT, type, mediaSegment);\n });\n }\n\n _onLoadingComplete() {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.LOADING_COMPLETE);\n });\n }\n\n _onRecoveredEarlyEof() {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.RECOVERED_EARLY_EOF);\n });\n }\n\n _onMediaInfo(mediaInfo) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.MEDIA_INFO, mediaInfo);\n });\n }\n\n _onStatisticsInfo(statisticsInfo) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.STATISTICS_INFO, statisticsInfo);\n });\n }\n\n _onIOError(type, info) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.IO_ERROR, type, info);\n });\n }\n\n _onDemuxError(type, info) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.DEMUX_ERROR, type, info);\n });\n }\n\n _onRecommendSeekpoint(milliseconds) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.RECOMMEND_SEEKPOINT, milliseconds);\n });\n }\n\n _onLoggingConfigChanged(config) {\n if (this._worker) {\n this._worker.postMessage({cmd: 'logging_config', param: config});\n }\n }\n\n _onWorkerMessage(e) {\n let message = e.data;\n let data = message.data;\n\n if (message.msg === 'destroyed' || this._workerDestroying) {\n this._workerDestroying = false;\n this._worker.terminate();\n this._worker = null;\n return;\n }\n\n switch (message.msg) {\n case TransmuxingEvents.INIT_SEGMENT:\n case TransmuxingEvents.MEDIA_SEGMENT:\n this._emitter.emit(message.msg, data.type, data.data);\n break;\n case TransmuxingEvents.LOADING_COMPLETE:\n case TransmuxingEvents.RECOVERED_EARLY_EOF:\n this._emitter.emit(message.msg);\n break;\n case TransmuxingEvents.MEDIA_INFO:\n Object.setPrototypeOf(data, MediaInfo.prototype);\n this._emitter.emit(message.msg, data);\n break;\n case TransmuxingEvents.STATISTICS_INFO:\n this._emitter.emit(message.msg, data);\n break;\n case TransmuxingEvents.IO_ERROR:\n case TransmuxingEvents.DEMUX_ERROR:\n this._emitter.emit(message.msg, data.type, data.info);\n break;\n case TransmuxingEvents.RECOMMEND_SEEKPOINT:\n this._emitter.emit(message.msg, data);\n break;\n case 'logcat_callback':\n Log.emitter.emit('log', data.type, data.logcat);\n break;\n default:\n break;\n }\n }\n\n}\n\nexport default Transmuxer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport MediaInfo from './media-info.js';\nimport FLVDemuxer from '../demux/flv-demuxer.js';\nimport MP4Remuxer from '../remux/mp4-remuxer.js';\nimport DemuxErrors from '../demux/demux-errors.js';\nimport IOController from '../io/io-controller.js';\nimport TransmuxingEvents from './transmuxing-events.js';\nimport {LoaderStatus, LoaderErrors} from '../io/loader.js';\n\n// Transmuxing (IO, Demuxing, Remuxing) controller, with multipart support\nclass TransmuxingController {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'TransmuxingController';\n this._emitter = new EventEmitter();\n\n this._config = config;\n\n // treat single part media as multipart media, which has only one segment\n if (!mediaDataSource.segments) {\n mediaDataSource.segments = [{\n duration: mediaDataSource.duration,\n filesize: mediaDataSource.filesize,\n url: mediaDataSource.url\n }];\n }\n\n // fill in default IO params if not exists\n if (typeof mediaDataSource.cors !== 'boolean') {\n mediaDataSource.cors = true;\n }\n if (typeof mediaDataSource.withCredentials !== 'boolean') {\n mediaDataSource.withCredentials = false;\n }\n\n this._mediaDataSource = mediaDataSource;\n this._currentSegmentIndex = 0;\n let totalDuration = 0;\n\n this._mediaDataSource.segments.forEach((segment) => {\n // timestampBase for each segment, and calculate total duration\n segment.timestampBase = totalDuration;\n totalDuration += segment.duration;\n // params needed by IOController\n segment.cors = mediaDataSource.cors;\n segment.withCredentials = mediaDataSource.withCredentials;\n // referrer policy control, if exist\n if (config.referrerPolicy) {\n segment.referrerPolicy = config.referrerPolicy;\n }\n });\n\n if (!isNaN(totalDuration) && this._mediaDataSource.duration !== totalDuration) {\n this._mediaDataSource.duration = totalDuration;\n }\n\n this._mediaInfo = null;\n this._demuxer = null;\n this._remuxer = null;\n this._ioctl = null;\n\n this._pendingSeekTime = null;\n this._pendingResolveSeekPoint = null;\n\n this._statisticsReporter = null;\n }\n\n destroy() {\n this._mediaInfo = null;\n this._mediaDataSource = null;\n\n if (this._statisticsReporter) {\n this._disableStatisticsReporter();\n }\n if (this._ioctl) {\n this._ioctl.destroy();\n this._ioctl = null;\n }\n if (this._demuxer) {\n this._demuxer.destroy();\n this._demuxer = null;\n }\n if (this._remuxer) {\n this._remuxer.destroy();\n this._remuxer = null;\n }\n\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n start() {\n this._loadSegment(0);\n this._enableStatisticsReporter();\n }\n\n _loadSegment(segmentIndex, optionalFrom) {\n this._currentSegmentIndex = segmentIndex;\n let dataSource = this._mediaDataSource.segments[segmentIndex];\n\n let ioctl = this._ioctl = new IOController(dataSource, this._config, segmentIndex);\n ioctl.onError = this._onIOException.bind(this);\n ioctl.onSeeked = this._onIOSeeked.bind(this);\n ioctl.onComplete = this._onIOComplete.bind(this);\n ioctl.onRedirect = this._onIORedirect.bind(this);\n ioctl.onRecoveredEarlyEof = this._onIORecoveredEarlyEof.bind(this);\n\n if (optionalFrom) {\n this._demuxer.bindDataSource(this._ioctl);\n } else {\n ioctl.onDataArrival = this._onInitChunkArrival.bind(this);\n }\n\n ioctl.open(optionalFrom);\n }\n\n stop() {\n this._internalAbort();\n this._disableStatisticsReporter();\n }\n\n _internalAbort() {\n if (this._ioctl) {\n this._ioctl.destroy();\n this._ioctl = null;\n }\n }\n\n pause() { // take a rest\n if (this._ioctl && this._ioctl.isWorking()) {\n this._ioctl.pause();\n this._disableStatisticsReporter();\n }\n }\n\n resume() {\n if (this._ioctl && this._ioctl.isPaused()) {\n this._ioctl.resume();\n this._enableStatisticsReporter();\n }\n }\n\n seek(milliseconds) {\n if (this._mediaInfo == null || !this._mediaInfo.isSeekable()) {\n return;\n }\n\n let targetSegmentIndex = this._searchSegmentIndexContains(milliseconds);\n\n if (targetSegmentIndex === this._currentSegmentIndex) {\n // intra-segment seeking\n let segmentInfo = this._mediaInfo.segments[targetSegmentIndex];\n\n if (segmentInfo == undefined) {\n // current segment loading started, but mediainfo hasn't received yet\n // wait for the metadata loaded, then seek to expected position\n this._pendingSeekTime = milliseconds;\n } else {\n let keyframe = segmentInfo.getNearestKeyframe(milliseconds);\n this._remuxer.seek(keyframe.milliseconds);\n this._ioctl.seek(keyframe.fileposition);\n // Will be resolved in _onRemuxerMediaSegmentArrival()\n this._pendingResolveSeekPoint = keyframe.milliseconds;\n }\n } else {\n // cross-segment seeking\n let targetSegmentInfo = this._mediaInfo.segments[targetSegmentIndex];\n\n if (targetSegmentInfo == undefined) {\n // target segment hasn't been loaded. We need metadata then seek to expected time\n this._pendingSeekTime = milliseconds;\n this._internalAbort();\n this._remuxer.seek();\n this._remuxer.insertDiscontinuity();\n this._loadSegment(targetSegmentIndex);\n // Here we wait for the metadata loaded, then seek to expected position\n } else {\n // We have target segment's metadata, direct seek to target position\n let keyframe = targetSegmentInfo.getNearestKeyframe(milliseconds);\n this._internalAbort();\n this._remuxer.seek(milliseconds);\n this._remuxer.insertDiscontinuity();\n this._demuxer.resetMediaInfo();\n this._demuxer.timestampBase = this._mediaDataSource.segments[targetSegmentIndex].timestampBase;\n this._loadSegment(targetSegmentIndex, keyframe.fileposition);\n this._pendingResolveSeekPoint = keyframe.milliseconds;\n this._reportSegmentMediaInfo(targetSegmentIndex);\n }\n }\n\n this._enableStatisticsReporter();\n }\n\n _searchSegmentIndexContains(milliseconds) {\n let segments = this._mediaDataSource.segments;\n let idx = segments.length - 1;\n\n for (let i = 0; i < segments.length; i++) {\n if (milliseconds < segments[i].timestampBase) {\n idx = i - 1;\n break;\n }\n }\n return idx;\n }\n\n _onInitChunkArrival(data, byteStart) {\n let probeData = null;\n let consumed = 0;\n\n if (byteStart > 0) {\n // IOController seeked immediately after opened, byteStart > 0 callback may received\n this._demuxer.bindDataSource(this._ioctl);\n this._demuxer.timestampBase = this._mediaDataSource.segments[this._currentSegmentIndex].timestampBase;\n\n consumed = this._demuxer.parseChunks(data, byteStart);\n } else if ((probeData = FLVDemuxer.probe(data)).match) {\n // Always create new FLVDemuxer\n this._demuxer = new FLVDemuxer(probeData, this._config);\n\n if (!this._remuxer) {\n this._remuxer = new MP4Remuxer(this._config);\n }\n\n let mds = this._mediaDataSource;\n if (mds.duration != undefined && !isNaN(mds.duration)) {\n this._demuxer.overridedDuration = mds.duration;\n }\n if (typeof mds.hasAudio === 'boolean') {\n this._demuxer.overridedHasAudio = mds.hasAudio;\n }\n if (typeof mds.hasVideo === 'boolean') {\n this._demuxer.overridedHasVideo = mds.hasVideo;\n }\n\n this._demuxer.timestampBase = mds.segments[this._currentSegmentIndex].timestampBase;\n\n this._demuxer.onError = this._onDemuxException.bind(this);\n this._demuxer.onMediaInfo = this._onMediaInfo.bind(this);\n\n this._remuxer.bindDataSource(this._demuxer\n .bindDataSource(this._ioctl\n ));\n\n this._remuxer.onInitSegment = this._onRemuxerInitSegmentArrival.bind(this);\n this._remuxer.onMediaSegment = this._onRemuxerMediaSegmentArrival.bind(this);\n\n consumed = this._demuxer.parseChunks(data, byteStart);\n } else {\n probeData = null;\n Log.e(this.TAG, 'Non-FLV, Unsupported media type!');\n Promise.resolve().then(() => {\n this._internalAbort();\n });\n this._emitter.emit(TransmuxingEvents.DEMUX_ERROR, DemuxErrors.FORMAT_UNSUPPORTED, 'Non-FLV, Unsupported media type');\n\n consumed = 0;\n }\n\n return consumed;\n }\n\n _onMediaInfo(mediaInfo) {\n if (this._mediaInfo == null) {\n // Store first segment's mediainfo as global mediaInfo\n this._mediaInfo = Object.assign({}, mediaInfo);\n this._mediaInfo.keyframesIndex = null;\n this._mediaInfo.segments = [];\n this._mediaInfo.segmentCount = this._mediaDataSource.segments.length;\n Object.setPrototypeOf(this._mediaInfo, MediaInfo.prototype);\n }\n\n let segmentInfo = Object.assign({}, mediaInfo);\n Object.setPrototypeOf(segmentInfo, MediaInfo.prototype);\n this._mediaInfo.segments[this._currentSegmentIndex] = segmentInfo;\n\n // notify mediaInfo update\n this._reportSegmentMediaInfo(this._currentSegmentIndex);\n\n if (this._pendingSeekTime != null) {\n Promise.resolve().then(() => {\n let target = this._pendingSeekTime;\n this._pendingSeekTime = null;\n this.seek(target);\n });\n }\n }\n\n _onIOSeeked() {\n this._remuxer.insertDiscontinuity();\n }\n\n _onIOComplete(extraData) {\n let segmentIndex = extraData;\n let nextSegmentIndex = segmentIndex + 1;\n\n if (nextSegmentIndex < this._mediaDataSource.segments.length) {\n this._internalAbort();\n this._loadSegment(nextSegmentIndex);\n } else {\n this._emitter.emit(TransmuxingEvents.LOADING_COMPLETE);\n this._disableStatisticsReporter();\n }\n }\n\n _onIORedirect(redirectedURL) {\n let segmentIndex = this._ioctl.extraData;\n this._mediaDataSource.segments[segmentIndex].redirectedURL = redirectedURL;\n }\n\n _onIORecoveredEarlyEof() {\n this._emitter.emit(TransmuxingEvents.RECOVERED_EARLY_EOF);\n }\n\n _onIOException(type, info) {\n Log.e(this.TAG, `IOException: type = ${type}, code = ${info.code}, msg = ${info.msg}`);\n this._emitter.emit(TransmuxingEvents.IO_ERROR, type, info);\n this._disableStatisticsReporter();\n }\n\n _onDemuxException(type, info) {\n Log.e(this.TAG, `DemuxException: type = ${type}, info = ${info}`);\n this._emitter.emit(TransmuxingEvents.DEMUX_ERROR, type, info);\n }\n\n _onRemuxerInitSegmentArrival(type, initSegment) {\n this._emitter.emit(TransmuxingEvents.INIT_SEGMENT, type, initSegment);\n }\n\n _onRemuxerMediaSegmentArrival(type, mediaSegment) {\n if (this._pendingSeekTime != null) {\n // Media segments after new-segment cross-seeking should be dropped.\n return;\n }\n this._emitter.emit(TransmuxingEvents.MEDIA_SEGMENT, type, mediaSegment);\n\n // Resolve pending seekPoint\n if (this._pendingResolveSeekPoint != null && type === 'video') {\n let syncPoints = mediaSegment.info.syncPoints;\n let seekpoint = this._pendingResolveSeekPoint;\n this._pendingResolveSeekPoint = null;\n\n // Safari: Pass PTS for recommend_seekpoint\n if (Browser.safari && syncPoints.length > 0 && syncPoints[0].originalDts === seekpoint) {\n seekpoint = syncPoints[0].pts;\n }\n // else: use original DTS (keyframe.milliseconds)\n\n this._emitter.emit(TransmuxingEvents.RECOMMEND_SEEKPOINT, seekpoint);\n }\n }\n\n _enableStatisticsReporter() {\n if (this._statisticsReporter == null) {\n this._statisticsReporter = self.setInterval(\n this._reportStatisticsInfo.bind(this),\n this._config.statisticsInfoReportInterval);\n }\n }\n\n _disableStatisticsReporter() {\n if (this._statisticsReporter) {\n self.clearInterval(this._statisticsReporter);\n this._statisticsReporter = null;\n }\n }\n\n _reportSegmentMediaInfo(segmentIndex) {\n let segmentInfo = this._mediaInfo.segments[segmentIndex];\n let exportInfo = Object.assign({}, segmentInfo);\n\n exportInfo.duration = this._mediaInfo.duration;\n exportInfo.segmentCount = this._mediaInfo.segmentCount;\n delete exportInfo.segments;\n delete exportInfo.keyframesIndex;\n\n this._emitter.emit(TransmuxingEvents.MEDIA_INFO, exportInfo);\n }\n\n _reportStatisticsInfo() {\n let info = {};\n\n info.url = this._ioctl.currentURL;\n info.hasRedirect = this._ioctl.hasRedirect;\n if (info.hasRedirect) {\n info.redirectedURL = this._ioctl.currentRedirectedURL;\n }\n\n info.speed = this._ioctl.currentSpeed;\n info.loaderType = this._ioctl.loaderType;\n info.currentSegmentIndex = this._currentSegmentIndex;\n info.totalSegmentCount = this._mediaDataSource.segments.length;\n\n this._emitter.emit(TransmuxingEvents.STATISTICS_INFO, info);\n }\n\n}\n\nexport default TransmuxingController;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst TransmuxingEvents = {\n IO_ERROR: 'io_error',\n DEMUX_ERROR: 'demux_error',\n INIT_SEGMENT: 'init_segment',\n MEDIA_SEGMENT: 'media_segment',\n LOADING_COMPLETE: 'loading_complete',\n RECOVERED_EARLY_EOF: 'recovered_early_eof',\n MEDIA_INFO: 'media_info',\n STATISTICS_INFO: 'statistics_info',\n RECOMMEND_SEEKPOINT: 'recommend_seekpoint'\n};\n\nexport default TransmuxingEvents;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport LoggingControl from '../utils/logging-control.js';\nimport Polyfill from '../utils/polyfill.js';\nimport TransmuxingController from './transmuxing-controller.js';\nimport TransmuxingEvents from './transmuxing-events.js';\n\n/* post message to worker:\n data: {\n cmd: string\n param: any\n }\n\n receive message from worker:\n data: {\n msg: string,\n data: any\n }\n */\n\nlet TransmuxingWorker = function (self) {\n\n let TAG = 'TransmuxingWorker';\n let controller = null;\n let logcatListener = onLogcatCallback.bind(this);\n\n Polyfill.install();\n\n self.addEventListener('message', function (e) {\n switch (e.data.cmd) {\n case 'init':\n controller = new TransmuxingController(e.data.param[0], e.data.param[1]);\n controller.on(TransmuxingEvents.IO_ERROR, onIOError.bind(this));\n controller.on(TransmuxingEvents.DEMUX_ERROR, onDemuxError.bind(this));\n controller.on(TransmuxingEvents.INIT_SEGMENT, onInitSegment.bind(this));\n controller.on(TransmuxingEvents.MEDIA_SEGMENT, onMediaSegment.bind(this));\n controller.on(TransmuxingEvents.LOADING_COMPLETE, onLoadingComplete.bind(this));\n controller.on(TransmuxingEvents.RECOVERED_EARLY_EOF, onRecoveredEarlyEof.bind(this));\n controller.on(TransmuxingEvents.MEDIA_INFO, onMediaInfo.bind(this));\n controller.on(TransmuxingEvents.STATISTICS_INFO, onStatisticsInfo.bind(this));\n controller.on(TransmuxingEvents.RECOMMEND_SEEKPOINT, onRecommendSeekpoint.bind(this));\n break;\n case 'destroy':\n if (controller) {\n controller.destroy();\n controller = null;\n }\n self.postMessage({msg: 'destroyed'});\n break;\n case 'start':\n controller.start();\n break;\n case 'stop':\n controller.stop();\n break;\n case 'seek':\n controller.seek(e.data.param);\n break;\n case 'pause':\n controller.pause();\n break;\n case 'resume':\n controller.resume();\n break;\n case 'logging_config': {\n let config = e.data.param;\n LoggingControl.applyConfig(config);\n\n if (config.enableCallback === true) {\n LoggingControl.addLogListener(logcatListener);\n } else {\n LoggingControl.removeLogListener(logcatListener);\n }\n break;\n }\n }\n });\n\n function onInitSegment(type, initSegment) {\n let obj = {\n msg: TransmuxingEvents.INIT_SEGMENT,\n data: {\n type: type,\n data: initSegment\n }\n };\n self.postMessage(obj, [initSegment.data]); // data: ArrayBuffer\n }\n\n function onMediaSegment(type, mediaSegment) {\n let obj = {\n msg: TransmuxingEvents.MEDIA_SEGMENT,\n data: {\n type: type,\n data: mediaSegment\n }\n };\n self.postMessage(obj, [mediaSegment.data]); // data: ArrayBuffer\n }\n\n function onLoadingComplete() {\n let obj = {\n msg: TransmuxingEvents.LOADING_COMPLETE\n };\n self.postMessage(obj);\n }\n\n function onRecoveredEarlyEof() {\n let obj = {\n msg: TransmuxingEvents.RECOVERED_EARLY_EOF\n };\n self.postMessage(obj);\n }\n\n function onMediaInfo(mediaInfo) {\n let obj = {\n msg: TransmuxingEvents.MEDIA_INFO,\n data: mediaInfo\n };\n self.postMessage(obj);\n }\n\n function onStatisticsInfo(statInfo) {\n let obj = {\n msg: TransmuxingEvents.STATISTICS_INFO,\n data: statInfo\n };\n self.postMessage(obj);\n }\n\n function onIOError(type, info) {\n self.postMessage({\n msg: TransmuxingEvents.IO_ERROR,\n data: {\n type: type,\n info: info\n }\n });\n }\n\n function onDemuxError(type, info) {\n self.postMessage({\n msg: TransmuxingEvents.DEMUX_ERROR,\n data: {\n type: type,\n info: info\n }\n });\n }\n\n function onRecommendSeekpoint(milliseconds) {\n self.postMessage({\n msg: TransmuxingEvents.RECOMMEND_SEEKPOINT,\n data: milliseconds\n });\n }\n\n function onLogcatCallback(type, str) {\n self.postMessage({\n msg: 'logcat_callback',\n data: {\n type: type,\n logcat: str\n }\n });\n }\n\n};\n\nexport default TransmuxingWorker;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport decodeUTF8 from '../utils/utf8-conv.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\nlet le = (function () {\n let buf = new ArrayBuffer(2);\n (new DataView(buf)).setInt16(0, 256, true); // little-endian write\n return (new Int16Array(buf))[0] === 256; // platform-spec read, if equal then LE\n})();\n\nclass AMF {\n\n static parseScriptData(arrayBuffer, dataOffset, dataSize) {\n let data = {};\n\n try {\n let name = AMF.parseValue(arrayBuffer, dataOffset, dataSize);\n let value = AMF.parseValue(arrayBuffer, dataOffset + name.size, dataSize - name.size);\n\n data[name.data] = value.data;\n } catch (e) {\n Log.e('AMF', e.toString());\n }\n\n return data;\n }\n\n static parseObject(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 3) {\n throw new IllegalStateException('Data not enough when parse ScriptDataObject');\n }\n let name = AMF.parseString(arrayBuffer, dataOffset, dataSize);\n let value = AMF.parseValue(arrayBuffer, dataOffset + name.size, dataSize - name.size);\n let isObjectEnd = value.objectEnd;\n\n return {\n data: {\n name: name.data,\n value: value.data\n },\n size: name.size + value.size,\n objectEnd: isObjectEnd\n };\n }\n\n static parseVariable(arrayBuffer, dataOffset, dataSize) {\n return AMF.parseObject(arrayBuffer, dataOffset, dataSize);\n }\n\n static parseString(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 2) {\n throw new IllegalStateException('Data not enough when parse String');\n }\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n let length = v.getUint16(0, !le);\n\n let str;\n if (length > 0) {\n str = decodeUTF8(new Uint8Array(arrayBuffer, dataOffset + 2, length));\n } else {\n str = '';\n }\n\n return {\n data: str,\n size: 2 + length\n };\n }\n\n static parseLongString(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 4) {\n throw new IllegalStateException('Data not enough when parse LongString');\n }\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n let length = v.getUint32(0, !le);\n\n let str;\n if (length > 0) {\n str = decodeUTF8(new Uint8Array(arrayBuffer, dataOffset + 4, length));\n } else {\n str = '';\n }\n\n return {\n data: str,\n size: 4 + length\n };\n }\n\n static parseDate(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 10) {\n throw new IllegalStateException('Data size invalid when parse Date');\n }\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n let timestamp = v.getFloat64(0, !le);\n let localTimeOffset = v.getInt16(8, !le);\n timestamp += localTimeOffset * 60 * 1000; // get UTC time\n\n return {\n data: new Date(timestamp),\n size: 8 + 2\n };\n }\n\n static parseValue(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 1) {\n throw new IllegalStateException('Data not enough when parse Value');\n }\n\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let offset = 1;\n let type = v.getUint8(0);\n let value;\n let objectEnd = false;\n\n try {\n switch (type) {\n case 0: // Number(Double) type\n value = v.getFloat64(1, !le);\n offset += 8;\n break;\n case 1: { // Boolean type\n let b = v.getUint8(1);\n value = b ? true : false;\n offset += 1;\n break;\n }\n case 2: { // String type\n let amfstr = AMF.parseString(arrayBuffer, dataOffset + 1, dataSize - 1);\n value = amfstr.data;\n offset += amfstr.size;\n break;\n }\n case 3: { // Object(s) type\n value = {};\n let terminal = 0; // workaround for malformed Objects which has missing ScriptDataObjectEnd\n if ((v.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {\n terminal = 3;\n }\n while (offset < dataSize - 4) { // 4 === type(UI8) + ScriptDataObjectEnd(UI24)\n let amfobj = AMF.parseObject(arrayBuffer, dataOffset + offset, dataSize - offset - terminal);\n if (amfobj.objectEnd)\n break;\n value[amfobj.data.name] = amfobj.data.value;\n offset += amfobj.size;\n }\n if (offset <= dataSize - 3) {\n let marker = v.getUint32(offset - 1, !le) & 0x00FFFFFF;\n if (marker === 9) {\n offset += 3;\n }\n }\n break;\n }\n case 8: { // ECMA array type (Mixed array)\n value = {};\n offset += 4; // ECMAArrayLength(UI32)\n let terminal = 0; // workaround for malformed MixedArrays which has missing ScriptDataObjectEnd\n if ((v.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {\n terminal = 3;\n }\n while (offset < dataSize - 8) { // 8 === type(UI8) + ECMAArrayLength(UI32) + ScriptDataVariableEnd(UI24)\n let amfvar = AMF.parseVariable(arrayBuffer, dataOffset + offset, dataSize - offset - terminal);\n if (amfvar.objectEnd)\n break;\n value[amfvar.data.name] = amfvar.data.value;\n offset += amfvar.size;\n }\n if (offset <= dataSize - 3) {\n let marker = v.getUint32(offset - 1, !le) & 0x00FFFFFF;\n if (marker === 9) {\n offset += 3;\n }\n }\n break;\n }\n case 9: // ScriptDataObjectEnd\n value = undefined;\n offset = 1;\n objectEnd = true;\n break;\n case 10: { // Strict array type\n // ScriptDataValue[n]. NOTE: according to video_file_format_spec_v10_1.pdf\n value = [];\n let strictArrayLength = v.getUint32(1, !le);\n offset += 4;\n for (let i = 0; i < strictArrayLength; i++) {\n let val = AMF.parseValue(arrayBuffer, dataOffset + offset, dataSize - offset);\n value.push(val.data);\n offset += val.size;\n }\n break;\n }\n case 11: { // Date type\n let date = AMF.parseDate(arrayBuffer, dataOffset + 1, dataSize - 1);\n value = date.data;\n offset += date.size;\n break;\n }\n case 12: { // Long string type\n let amfLongStr = AMF.parseString(arrayBuffer, dataOffset + 1, dataSize - 1);\n value = amfLongStr.data;\n offset += amfLongStr.size;\n break;\n }\n default:\n // ignore and skip\n offset = dataSize;\n Log.w('AMF', 'Unsupported AMF value type ' + type);\n }\n } catch (e) {\n Log.e('AMF', e.toString());\n }\n\n return {\n data: value,\n size: offset,\n objectEnd: objectEnd\n };\n }\n\n}\n\nexport default AMF;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst DemuxErrors = {\n OK: 'OK',\n FORMAT_ERROR: 'FormatError',\n FORMAT_UNSUPPORTED: 'FormatUnsupported',\n CODEC_UNSUPPORTED: 'CodecUnsupported'\n};\n\nexport default DemuxErrors;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {IllegalStateException, InvalidArgumentException} from '../utils/exception.js';\n\n// Exponential-Golomb buffer decoder\nclass ExpGolomb {\n\n constructor(uint8array) {\n this.TAG = 'ExpGolomb';\n\n this._buffer = uint8array;\n this._buffer_index = 0;\n this._total_bytes = uint8array.byteLength;\n this._total_bits = uint8array.byteLength * 8;\n this._current_word = 0;\n this._current_word_bits_left = 0;\n }\n\n destroy() {\n this._buffer = null;\n }\n\n _fillCurrentWord() {\n let buffer_bytes_left = this._total_bytes - this._buffer_index;\n if (buffer_bytes_left <= 0)\n throw new IllegalStateException('ExpGolomb: _fillCurrentWord() but no bytes available');\n\n let bytes_read = Math.min(4, buffer_bytes_left);\n let word = new Uint8Array(4);\n word.set(this._buffer.subarray(this._buffer_index, this._buffer_index + bytes_read));\n this._current_word = new DataView(word.buffer).getUint32(0, false);\n\n this._buffer_index += bytes_read;\n this._current_word_bits_left = bytes_read * 8;\n }\n\n readBits(bits) {\n if (bits > 32)\n throw new InvalidArgumentException('ExpGolomb: readBits() bits exceeded max 32bits!');\n\n if (bits <= this._current_word_bits_left) {\n let result = this._current_word >>> (32 - bits);\n this._current_word <<= bits;\n this._current_word_bits_left -= bits;\n return result;\n }\n\n let result = this._current_word_bits_left ? this._current_word : 0;\n result = result >>> (32 - this._current_word_bits_left);\n let bits_need_left = bits - this._current_word_bits_left;\n\n this._fillCurrentWord();\n let bits_read_next = Math.min(bits_need_left, this._current_word_bits_left);\n\n let result2 = this._current_word >>> (32 - bits_read_next);\n this._current_word <<= bits_read_next;\n this._current_word_bits_left -= bits_read_next;\n\n result = (result << bits_read_next) | result2;\n return result;\n }\n\n readBool() {\n return this.readBits(1) === 1;\n }\n\n readByte() {\n return this.readBits(8);\n }\n\n _skipLeadingZero() {\n let zero_count;\n for (zero_count = 0; zero_count < this._current_word_bits_left; zero_count++) {\n if (0 !== (this._current_word & (0x80000000 >>> zero_count))) {\n this._current_word <<= zero_count;\n this._current_word_bits_left -= zero_count;\n return zero_count;\n }\n }\n this._fillCurrentWord();\n return zero_count + this._skipLeadingZero();\n }\n\n readUEG() { // unsigned exponential golomb\n let leading_zeros = this._skipLeadingZero();\n return this.readBits(leading_zeros + 1) - 1;\n }\n\n readSEG() { // signed exponential golomb\n let value = this.readUEG();\n if (value & 0x01) {\n return (value + 1) >>> 1;\n } else {\n return -1 * (value >>> 1);\n }\n }\n\n}\n\nexport default ExpGolomb;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport AMF from './amf-parser.js';\nimport SPSParser from './sps-parser.js';\nimport DemuxErrors from './demux-errors.js';\nimport MediaInfo from '../core/media-info.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\nfunction Swap16(src) {\n return (((src >>> 8) & 0xFF) |\n ((src & 0xFF) << 8));\n}\n\nfunction Swap32(src) {\n return (((src & 0xFF000000) >>> 24) |\n ((src & 0x00FF0000) >>> 8) |\n ((src & 0x0000FF00) << 8) |\n ((src & 0x000000FF) << 24));\n}\n\nfunction ReadBig32(array, index) {\n return ((array[index] << 24) |\n (array[index + 1] << 16) |\n (array[index + 2] << 8) |\n (array[index + 3]));\n}\n\n\nclass FLVDemuxer {\n\n constructor(probeData, config) {\n this.TAG = 'FLVDemuxer';\n\n this._config = config;\n\n this._onError = null;\n this._onMediaInfo = null;\n this._onTrackMetadata = null;\n this._onDataAvailable = null;\n\n this._dataOffset = probeData.dataOffset;\n this._firstParse = true;\n this._dispatch = false;\n\n this._hasAudio = probeData.hasAudioTrack;\n this._hasVideo = probeData.hasVideoTrack;\n\n this._hasAudioFlagOverrided = false;\n this._hasVideoFlagOverrided = false;\n\n this._audioInitialMetadataDispatched = false;\n this._videoInitialMetadataDispatched = false;\n\n this._mediaInfo = new MediaInfo();\n this._mediaInfo.hasAudio = this._hasAudio;\n this._mediaInfo.hasVideo = this._hasVideo;\n this._metadata = null;\n this._audioMetadata = null;\n this._videoMetadata = null;\n\n this._naluLengthSize = 4;\n this._timestampBase = 0; // int32, in milliseconds\n this._timescale = 1000;\n this._duration = 0; // int32, in milliseconds\n this._durationOverrided = false;\n this._referenceFrameRate = {\n fixed: true,\n fps: 23.976,\n fps_num: 23976,\n fps_den: 1000\n };\n\n this._flvSoundRateTable = [5500, 11025, 22050, 44100, 48000];\n\n this._mpegSamplingRates = [\n 96000, 88200, 64000, 48000, 44100, 32000,\n 24000, 22050, 16000, 12000, 11025, 8000, 7350\n ];\n\n this._mpegAudioV10SampleRateTable = [44100, 48000, 32000, 0];\n this._mpegAudioV20SampleRateTable = [22050, 24000, 16000, 0];\n this._mpegAudioV25SampleRateTable = [11025, 12000, 8000, 0];\n\n this._mpegAudioL1BitRateTable = [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1];\n this._mpegAudioL2BitRateTable = [0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1];\n this._mpegAudioL3BitRateTable = [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1];\n\n this._videoTrack = {type: 'video', id: 1, sequenceNumber: 0, samples: [], length: 0};\n this._audioTrack = {type: 'audio', id: 2, sequenceNumber: 0, samples: [], length: 0};\n\n this._littleEndian = (function () {\n let buf = new ArrayBuffer(2);\n (new DataView(buf)).setInt16(0, 256, true); // little-endian write\n return (new Int16Array(buf))[0] === 256; // platform-spec read, if equal then LE\n })();\n }\n\n destroy() {\n this._mediaInfo = null;\n this._metadata = null;\n this._audioMetadata = null;\n this._videoMetadata = null;\n this._videoTrack = null;\n this._audioTrack = null;\n\n this._onError = null;\n this._onMediaInfo = null;\n this._onTrackMetadata = null;\n this._onDataAvailable = null;\n }\n\n static probe(buffer) {\n let data = new Uint8Array(buffer);\n let mismatch = {match: false};\n\n if (data[0] !== 0x46 || data[1] !== 0x4C || data[2] !== 0x56 || data[3] !== 0x01) {\n return mismatch;\n }\n\n let hasAudio = ((data[4] & 4) >>> 2) !== 0;\n let hasVideo = (data[4] & 1) !== 0;\n\n let offset = ReadBig32(data, 5);\n\n if (offset < 9) {\n return mismatch;\n }\n\n return {\n match: true,\n consumed: offset,\n dataOffset: offset,\n hasAudioTrack: hasAudio,\n hasVideoTrack: hasVideo\n };\n }\n\n bindDataSource(loader) {\n loader.onDataArrival = this.parseChunks.bind(this);\n return this;\n }\n\n // prototype: function(type: string, metadata: any): void\n get onTrackMetadata() {\n return this._onTrackMetadata;\n }\n\n set onTrackMetadata(callback) {\n this._onTrackMetadata = callback;\n }\n\n // prototype: function(mediaInfo: MediaInfo): void\n get onMediaInfo() {\n return this._onMediaInfo;\n }\n\n set onMediaInfo(callback) {\n this._onMediaInfo = callback;\n }\n\n // prototype: function(type: number, info: string): void\n get onError() {\n return this._onError;\n }\n\n set onError(callback) {\n this._onError = callback;\n }\n\n // prototype: function(videoTrack: any, audioTrack: any): void\n get onDataAvailable() {\n return this._onDataAvailable;\n }\n\n set onDataAvailable(callback) {\n this._onDataAvailable = callback;\n }\n\n // timestamp base for output samples, must be in milliseconds\n get timestampBase() {\n return this._timestampBase;\n }\n\n set timestampBase(base) {\n this._timestampBase = base;\n }\n\n get overridedDuration() {\n return this._duration;\n }\n\n // Force-override media duration. Must be in milliseconds, int32\n set overridedDuration(duration) {\n this._durationOverrided = true;\n this._duration = duration;\n this._mediaInfo.duration = duration;\n }\n\n // Force-override audio track present flag, boolean\n set overridedHasAudio(hasAudio) {\n this._hasAudioFlagOverrided = true;\n this._hasAudio = hasAudio;\n this._mediaInfo.hasAudio = hasAudio;\n }\n\n // Force-override video track present flag, boolean\n set overridedHasVideo(hasVideo) {\n this._hasVideoFlagOverrided = true;\n this._hasVideo = hasVideo;\n this._mediaInfo.hasVideo = hasVideo;\n }\n\n resetMediaInfo() {\n this._mediaInfo = new MediaInfo();\n }\n\n _isInitialMetadataDispatched() {\n if (this._hasAudio && this._hasVideo) { // both audio & video\n return this._audioInitialMetadataDispatched && this._videoInitialMetadataDispatched;\n }\n if (this._hasAudio && !this._hasVideo) { // audio only\n return this._audioInitialMetadataDispatched;\n }\n if (!this._hasAudio && this._hasVideo) { // video only\n return this._videoInitialMetadataDispatched;\n }\n return false;\n }\n\n // function parseChunks(chunk: ArrayBuffer, byteStart: number): number;\n parseChunks(chunk, byteStart) {\n if (!this._onError || !this._onMediaInfo || !this._onTrackMetadata || !this._onDataAvailable) {\n throw new IllegalStateException('Flv: onError & onMediaInfo & onTrackMetadata & onDataAvailable callback must be specified');\n }\n\n let offset = 0;\n let le = this._littleEndian;\n\n if (byteStart === 0) { // buffer with FLV header\n if (chunk.byteLength > 13) {\n let probeData = FLVDemuxer.probe(chunk);\n offset = probeData.dataOffset;\n } else {\n return 0;\n }\n }\n\n if (this._firstParse) { // handle PreviousTagSize0 before Tag1\n this._firstParse = false;\n if (byteStart + offset !== this._dataOffset) {\n Log.w(this.TAG, 'First time parsing but chunk byteStart invalid!');\n }\n\n let v = new DataView(chunk, offset);\n let prevTagSize0 = v.getUint32(0, !le);\n if (prevTagSize0 !== 0) {\n Log.w(this.TAG, 'PrevTagSize0 !== 0 !!!');\n }\n offset += 4;\n }\n\n while (offset < chunk.byteLength) {\n this._dispatch = true;\n\n let v = new DataView(chunk, offset);\n\n if (offset + 11 + 4 > chunk.byteLength) {\n // data not enough for parsing an flv tag\n break;\n }\n\n let tagType = v.getUint8(0);\n let dataSize = v.getUint32(0, !le) & 0x00FFFFFF;\n\n if (offset + 11 + dataSize + 4 > chunk.byteLength) {\n // data not enough for parsing actual data body\n break;\n }\n\n if (tagType !== 8 && tagType !== 9 && tagType !== 18) {\n Log.w(this.TAG, `Unsupported tag type ${tagType}, skipped`);\n // consume the whole tag (skip it)\n offset += 11 + dataSize + 4;\n continue;\n }\n\n let ts2 = v.getUint8(4);\n let ts1 = v.getUint8(5);\n let ts0 = v.getUint8(6);\n let ts3 = v.getUint8(7);\n\n let timestamp = ts0 | (ts1 << 8) | (ts2 << 16) | (ts3 << 24);\n\n let streamId = v.getUint32(7, !le) & 0x00FFFFFF;\n if (streamId !== 0) {\n Log.w(this.TAG, 'Meet tag which has StreamID != 0!');\n }\n\n let dataOffset = offset + 11;\n\n switch (tagType) {\n case 8: // Audio\n this._parseAudioData(chunk, dataOffset, dataSize, timestamp);\n break;\n case 9: // Video\n this._parseVideoData(chunk, dataOffset, dataSize, timestamp, byteStart + offset);\n break;\n case 18: // ScriptDataObject\n this._parseScriptData(chunk, dataOffset, dataSize);\n break;\n }\n\n let prevTagSize = v.getUint32(11 + dataSize, !le);\n if (prevTagSize !== 11 + dataSize) {\n Log.w(this.TAG, `Invalid PrevTagSize ${prevTagSize}`);\n }\n\n offset += 11 + dataSize + 4; // tagBody + dataSize + prevTagSize\n }\n\n // dispatch parsed frames to consumer (typically, the remuxer)\n if (this._isInitialMetadataDispatched()) {\n if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {\n this._onDataAvailable(this._audioTrack, this._videoTrack);\n }\n }\n\n return offset; // consumed bytes, just equals latest offset index\n }\n\n _parseScriptData(arrayBuffer, dataOffset, dataSize) {\n let scriptData = AMF.parseScriptData(arrayBuffer, dataOffset, dataSize);\n\n if (scriptData.hasOwnProperty('onMetaData')) {\n if (scriptData.onMetaData == null || typeof scriptData.onMetaData !== 'object') {\n Log.w(this.TAG, 'Invalid onMetaData structure!');\n return;\n }\n if (this._metadata) {\n Log.w(this.TAG, 'Found another onMetaData tag!');\n }\n this._metadata = scriptData;\n let onMetaData = this._metadata.onMetaData;\n\n if (typeof onMetaData.hasAudio === 'boolean') { // hasAudio\n if (this._hasAudioFlagOverrided === false) {\n this._hasAudio = onMetaData.hasAudio;\n this._mediaInfo.hasAudio = this._hasAudio;\n }\n }\n if (typeof onMetaData.hasVideo === 'boolean') { // hasVideo\n if (this._hasVideoFlagOverrided === false) {\n this._hasVideo = onMetaData.hasVideo;\n this._mediaInfo.hasVideo = this._hasVideo;\n }\n }\n if (typeof onMetaData.audiodatarate === 'number') { // audiodatarate\n this._mediaInfo.audioDataRate = onMetaData.audiodatarate;\n }\n if (typeof onMetaData.videodatarate === 'number') { // videodatarate\n this._mediaInfo.videoDataRate = onMetaData.videodatarate;\n }\n if (typeof onMetaData.width === 'number') { // width\n this._mediaInfo.width = onMetaData.width;\n }\n if (typeof onMetaData.height === 'number') { // height\n this._mediaInfo.height = onMetaData.height;\n }\n if (typeof onMetaData.duration === 'number') { // duration\n if (!this._durationOverrided) {\n let duration = Math.floor(onMetaData.duration * this._timescale);\n this._duration = duration;\n this._mediaInfo.duration = duration;\n }\n } else {\n this._mediaInfo.duration = 0;\n }\n if (typeof onMetaData.framerate === 'number') { // framerate\n let fps_num = Math.floor(onMetaData.framerate * 1000);\n if (fps_num > 0) {\n let fps = fps_num / 1000;\n this._referenceFrameRate.fixed = true;\n this._referenceFrameRate.fps = fps;\n this._referenceFrameRate.fps_num = fps_num;\n this._referenceFrameRate.fps_den = 1000;\n this._mediaInfo.fps = fps;\n }\n }\n if (typeof onMetaData.keyframes === 'object') { // keyframes\n this._mediaInfo.hasKeyframesIndex = true;\n let keyframes = onMetaData.keyframes;\n this._mediaInfo.keyframesIndex = this._parseKeyframesIndex(keyframes);\n onMetaData.keyframes = null; // keyframes has been extracted, remove it\n } else {\n this._mediaInfo.hasKeyframesIndex = false;\n }\n this._dispatch = false;\n this._mediaInfo.metadata = onMetaData;\n Log.v(this.TAG, 'Parsed onMetaData');\n if (this._mediaInfo.isComplete()) {\n this._onMediaInfo(this._mediaInfo);\n }\n }\n }\n\n _parseKeyframesIndex(keyframes) {\n let times = [];\n let filepositions = [];\n\n // ignore first keyframe which is actually AVC Sequence Header (AVCDecoderConfigurationRecord)\n for (let i = 1; i < keyframes.times.length; i++) {\n let time = this._timestampBase + Math.floor(keyframes.times[i] * 1000);\n times.push(time);\n filepositions.push(keyframes.filepositions[i]);\n }\n\n return {\n times: times,\n filepositions: filepositions\n };\n }\n\n _parseAudioData(arrayBuffer, dataOffset, dataSize, tagTimestamp) {\n if (dataSize <= 1) {\n Log.w(this.TAG, 'Flv: Invalid audio packet, missing SoundData payload!');\n return;\n }\n\n if (this._hasAudioFlagOverrided === true && this._hasAudio === false) {\n // If hasAudio: false indicated explicitly in MediaDataSource,\n // Ignore all the audio packets\n return;\n }\n\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let soundSpec = v.getUint8(0);\n\n let soundFormat = soundSpec >>> 4;\n if (soundFormat !== 2 && soundFormat !== 10) { // MP3 or AAC\n this._onError(DemuxErrors.CODEC_UNSUPPORTED, 'Flv: Unsupported audio codec idx: ' + soundFormat);\n return;\n }\n\n let soundRate = 0;\n let soundRateIndex = (soundSpec & 12) >>> 2;\n if (soundRateIndex >= 0 && soundRateIndex <= 4) {\n soundRate = this._flvSoundRateTable[soundRateIndex];\n } else {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid audio sample rate idx: ' + soundRateIndex);\n return;\n }\n\n let soundSize = (soundSpec & 2) >>> 1; // unused\n let soundType = (soundSpec & 1);\n\n\n let meta = this._audioMetadata;\n let track = this._audioTrack;\n\n if (!meta) {\n if (this._hasAudio === false && this._hasAudioFlagOverrided === false) {\n this._hasAudio = true;\n this._mediaInfo.hasAudio = true;\n }\n\n // initial metadata\n meta = this._audioMetadata = {};\n meta.type = 'audio';\n meta.id = track.id;\n meta.timescale = this._timescale;\n meta.duration = this._duration;\n meta.audioSampleRate = soundRate;\n meta.channelCount = (soundType === 0 ? 1 : 2);\n }\n\n if (soundFormat === 10) { // AAC\n let aacData = this._parseAACAudioData(arrayBuffer, dataOffset + 1, dataSize - 1);\n if (aacData == undefined) {\n return;\n }\n\n if (aacData.packetType === 0) { // AAC sequence header (AudioSpecificConfig)\n if (meta.config) {\n Log.w(this.TAG, 'Found another AudioSpecificConfig!');\n }\n let misc = aacData.data;\n meta.audioSampleRate = misc.samplingRate;\n meta.channelCount = misc.channelCount;\n meta.codec = misc.codec;\n meta.originalCodec = misc.originalCodec;\n meta.config = misc.config;\n // The decode result of an aac sample is 1024 PCM samples\n meta.refSampleDuration = 1024 / meta.audioSampleRate * meta.timescale;\n Log.v(this.TAG, 'Parsed AudioSpecificConfig');\n\n if (this._isInitialMetadataDispatched()) {\n // Non-initial metadata, force dispatch (or flush) parsed frames to remuxer\n if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {\n this._onDataAvailable(this._audioTrack, this._videoTrack);\n }\n } else {\n this._audioInitialMetadataDispatched = true;\n }\n // then notify new metadata\n this._dispatch = false;\n this._onTrackMetadata('audio', meta);\n\n let mi = this._mediaInfo;\n mi.audioCodec = meta.originalCodec;\n mi.audioSampleRate = meta.audioSampleRate;\n mi.audioChannelCount = meta.channelCount;\n if (mi.hasVideo) {\n if (mi.videoCodec != null) {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + ',' + mi.audioCodec + '\"';\n }\n } else {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.audioCodec + '\"';\n }\n if (mi.isComplete()) {\n this._onMediaInfo(mi);\n }\n } else if (aacData.packetType === 1) { // AAC raw frame data\n let dts = this._timestampBase + tagTimestamp;\n let aacSample = {unit: aacData.data, dts: dts, pts: dts};\n track.samples.push(aacSample);\n track.length += aacData.data.length;\n } else {\n Log.e(this.TAG, `Flv: Unsupported AAC data type ${aacData.packetType}`);\n }\n } else if (soundFormat === 2) { // MP3\n if (!meta.codec) {\n // We need metadata for mp3 audio track, extract info from frame header\n let misc = this._parseMP3AudioData(arrayBuffer, dataOffset + 1, dataSize - 1, true);\n if (misc == undefined) {\n return;\n }\n meta.audioSampleRate = misc.samplingRate;\n meta.channelCount = misc.channelCount;\n meta.codec = misc.codec;\n meta.originalCodec = misc.originalCodec;\n // The decode result of an mp3 sample is 1152 PCM samples\n meta.refSampleDuration = 1152 / meta.audioSampleRate * meta.timescale;\n Log.v(this.TAG, 'Parsed MPEG Audio Frame Header');\n\n this._audioInitialMetadataDispatched = true;\n this._onTrackMetadata('audio', meta);\n\n let mi = this._mediaInfo;\n mi.audioCodec = meta.codec;\n mi.audioSampleRate = meta.audioSampleRate;\n mi.audioChannelCount = meta.channelCount;\n mi.audioDataRate = misc.bitRate;\n if (mi.hasVideo) {\n if (mi.videoCodec != null) {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + ',' + mi.audioCodec + '\"';\n }\n } else {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.audioCodec + '\"';\n }\n if (mi.isComplete()) {\n this._onMediaInfo(mi);\n }\n }\n\n // This packet is always a valid audio packet, extract it\n let data = this._parseMP3AudioData(arrayBuffer, dataOffset + 1, dataSize - 1, false);\n if (data == undefined) {\n return;\n }\n let dts = this._timestampBase + tagTimestamp;\n let mp3Sample = {unit: data, dts: dts, pts: dts};\n track.samples.push(mp3Sample);\n track.length += data.length;\n }\n }\n\n _parseAACAudioData(arrayBuffer, dataOffset, dataSize) {\n if (dataSize <= 1) {\n Log.w(this.TAG, 'Flv: Invalid AAC packet, missing AACPacketType or/and Data!');\n return;\n }\n\n let result = {};\n let array = new Uint8Array(arrayBuffer, dataOffset, dataSize);\n\n result.packetType = array[0];\n\n if (array[0] === 0) {\n result.data = this._parseAACAudioSpecificConfig(arrayBuffer, dataOffset + 1, dataSize - 1);\n } else {\n result.data = array.subarray(1);\n }\n\n return result;\n }\n\n _parseAACAudioSpecificConfig(arrayBuffer, dataOffset, dataSize) {\n let array = new Uint8Array(arrayBuffer, dataOffset, dataSize);\n let config = null;\n\n /* Audio Object Type:\n 0: Null\n 1: AAC Main\n 2: AAC LC\n 3: AAC SSR (Scalable Sample Rate)\n 4: AAC LTP (Long Term Prediction)\n 5: HE-AAC / SBR (Spectral Band Replication)\n 6: AAC Scalable\n */\n\n let audioObjectType = 0;\n let originalAudioObjectType = 0;\n let audioExtensionObjectType = null;\n let samplingIndex = 0;\n let extensionSamplingIndex = null;\n\n // 5 bits\n audioObjectType = originalAudioObjectType = array[0] >>> 3;\n // 4 bits\n samplingIndex = ((array[0] & 0x07) << 1) | (array[1] >>> 7);\n if (samplingIndex < 0 || samplingIndex >= this._mpegSamplingRates.length) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: AAC invalid sampling frequency index!');\n return;\n }\n\n let samplingFrequence = this._mpegSamplingRates[samplingIndex];\n\n // 4 bits\n let channelConfig = (array[1] & 0x78) >>> 3;\n if (channelConfig < 0 || channelConfig >= 8) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: AAC invalid channel configuration');\n return;\n }\n\n if (audioObjectType === 5) { // HE-AAC?\n // 4 bits\n extensionSamplingIndex = ((array[1] & 0x07) << 1) | (array[2] >>> 7);\n // 5 bits\n audioExtensionObjectType = (array[2] & 0x7C) >>> 2;\n }\n\n // workarounds for various browsers\n let userAgent = self.navigator.userAgent.toLowerCase();\n\n if (userAgent.indexOf('firefox') !== -1) {\n // firefox: use SBR (HE-AAC) if freq less than 24kHz\n if (samplingIndex >= 6) {\n audioObjectType = 5;\n config = new Array(4);\n extensionSamplingIndex = samplingIndex - 3;\n } else { // use LC-AAC\n audioObjectType = 2;\n config = new Array(2);\n extensionSamplingIndex = samplingIndex;\n }\n } else if (userAgent.indexOf('android') !== -1) {\n // android: always use LC-AAC\n audioObjectType = 2;\n config = new Array(2);\n extensionSamplingIndex = samplingIndex;\n } else {\n // for other browsers, e.g. chrome...\n // Always use HE-AAC to make it easier to switch aac codec profile\n audioObjectType = 5;\n extensionSamplingIndex = samplingIndex;\n config = new Array(4);\n\n if (samplingIndex >= 6) {\n extensionSamplingIndex = samplingIndex - 3;\n } else if (channelConfig === 1) { // Mono channel\n audioObjectType = 2;\n config = new Array(2);\n extensionSamplingIndex = samplingIndex;\n }\n }\n\n config[0] = audioObjectType << 3;\n config[0] |= (samplingIndex & 0x0F) >>> 1;\n config[1] = (samplingIndex & 0x0F) << 7;\n config[1] |= (channelConfig & 0x0F) << 3;\n if (audioObjectType === 5) {\n config[1] |= ((extensionSamplingIndex & 0x0F) >>> 1);\n config[2] = (extensionSamplingIndex & 0x01) << 7;\n // extended audio object type: force to 2 (LC-AAC)\n config[2] |= (2 << 2);\n config[3] = 0;\n }\n\n return {\n config: config,\n samplingRate: samplingFrequence,\n channelCount: channelConfig,\n codec: 'mp4a.40.' + audioObjectType,\n originalCodec: 'mp4a.40.' + originalAudioObjectType\n };\n }\n\n _parseMP3AudioData(arrayBuffer, dataOffset, dataSize, requestHeader) {\n if (dataSize < 4) {\n Log.w(this.TAG, 'Flv: Invalid MP3 packet, header missing!');\n return;\n }\n\n let le = this._littleEndian;\n let array = new Uint8Array(arrayBuffer, dataOffset, dataSize);\n let result = null;\n\n if (requestHeader) {\n if (array[0] !== 0xFF) {\n return;\n }\n let ver = (array[1] >>> 3) & 0x03;\n let layer = (array[1] & 0x06) >> 1;\n\n let bitrate_index = (array[2] & 0xF0) >>> 4;\n let sampling_freq_index = (array[2] & 0x0C) >>> 2;\n\n let channel_mode = (array[3] >>> 6) & 0x03;\n let channel_count = channel_mode !== 3 ? 2 : 1;\n\n let sample_rate = 0;\n let bit_rate = 0;\n let object_type = 34; // Layer-3, listed in MPEG-4 Audio Object Types\n\n let codec = 'mp3';\n\n switch (ver) {\n case 0: // MPEG 2.5\n sample_rate = this._mpegAudioV25SampleRateTable[sampling_freq_index];\n break;\n case 2: // MPEG 2\n sample_rate = this._mpegAudioV20SampleRateTable[sampling_freq_index];\n break;\n case 3: // MPEG 1\n sample_rate = this._mpegAudioV10SampleRateTable[sampling_freq_index];\n break;\n }\n\n switch (layer) {\n case 1: // Layer 3\n object_type = 34;\n if (bitrate_index < this._mpegAudioL3BitRateTable.length) {\n bit_rate = this._mpegAudioL3BitRateTable[bitrate_index];\n }\n break;\n case 2: // Layer 2\n object_type = 33;\n if (bitrate_index < this._mpegAudioL2BitRateTable.length) {\n bit_rate = this._mpegAudioL2BitRateTable[bitrate_index];\n }\n break;\n case 3: // Layer 1\n object_type = 32;\n if (bitrate_index < this._mpegAudioL1BitRateTable.length) {\n bit_rate = this._mpegAudioL1BitRateTable[bitrate_index];\n }\n break;\n }\n\n result = {\n bitRate: bit_rate,\n samplingRate: sample_rate,\n channelCount: channel_count,\n codec: codec,\n originalCodec: codec\n };\n } else {\n result = array;\n }\n\n return result;\n }\n\n _parseVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition) {\n if (dataSize <= 1) {\n Log.w(this.TAG, 'Flv: Invalid video packet, missing VideoData payload!');\n return;\n }\n\n if (this._hasVideoFlagOverrided === true && this._hasVideo === false) {\n // If hasVideo: false indicated explicitly in MediaDataSource,\n // Ignore all the video packets\n return;\n }\n\n let spec = (new Uint8Array(arrayBuffer, dataOffset, dataSize))[0];\n\n let frameType = (spec & 240) >>> 4;\n let codecId = spec & 15;\n\n if (codecId !== 7) {\n this._onError(DemuxErrors.CODEC_UNSUPPORTED, `Flv: Unsupported codec in video frame: ${codecId}`);\n return;\n }\n\n this._parseAVCVideoPacket(arrayBuffer, dataOffset + 1, dataSize - 1, tagTimestamp, tagPosition, frameType);\n }\n\n _parseAVCVideoPacket(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType) {\n if (dataSize < 4) {\n Log.w(this.TAG, 'Flv: Invalid AVC packet, missing AVCPacketType or/and CompositionTime');\n return;\n }\n\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let packetType = v.getUint8(0);\n let cts = v.getUint32(0, !le) & 0x00FFFFFF;\n\n if (packetType === 0) { // AVCDecoderConfigurationRecord\n this._parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset + 4, dataSize - 4);\n } else if (packetType === 1) { // One or more Nalus\n this._parseAVCVideoData(arrayBuffer, dataOffset + 4, dataSize - 4, tagTimestamp, tagPosition, frameType, cts);\n } else if (packetType === 2) {\n // empty, AVC end of sequence\n } else {\n this._onError(DemuxErrors.FORMAT_ERROR, `Flv: Invalid video packet type ${packetType}`);\n return;\n }\n }\n\n _parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 7) {\n Log.w(this.TAG, 'Flv: Invalid AVCDecoderConfigurationRecord, lack of data!');\n return;\n }\n\n let meta = this._videoMetadata;\n let track = this._videoTrack;\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n if (!meta) {\n if (this._hasVideo === false && this._hasVideoFlagOverrided === false) {\n this._hasVideo = true;\n this._mediaInfo.hasVideo = true;\n }\n\n meta = this._videoMetadata = {};\n meta.type = 'video';\n meta.id = track.id;\n meta.timescale = this._timescale;\n meta.duration = this._duration;\n } else {\n if (typeof meta.avcc !== 'undefined') {\n Log.w(this.TAG, 'Found another AVCDecoderConfigurationRecord!');\n }\n }\n\n let version = v.getUint8(0); // configurationVersion\n let avcProfile = v.getUint8(1); // avcProfileIndication\n let profileCompatibility = v.getUint8(2); // profile_compatibility\n let avcLevel = v.getUint8(3); // AVCLevelIndication\n\n if (version !== 1 || avcProfile === 0) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord');\n return;\n }\n\n this._naluLengthSize = (v.getUint8(4) & 3) + 1; // lengthSizeMinusOne\n if (this._naluLengthSize !== 3 && this._naluLengthSize !== 4) { // holy shit!!!\n this._onError(DemuxErrors.FORMAT_ERROR, `Flv: Strange NaluLengthSizeMinusOne: ${this._naluLengthSize - 1}`);\n return;\n }\n\n let spsCount = v.getUint8(5) & 31; // numOfSequenceParameterSets\n if (spsCount === 0) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord: No SPS');\n return;\n } else if (spsCount > 1) {\n Log.w(this.TAG, `Flv: Strange AVCDecoderConfigurationRecord: SPS Count = ${spsCount}`);\n }\n\n let offset = 6;\n\n for (let i = 0; i < spsCount; i++) {\n let len = v.getUint16(offset, !le); // sequenceParameterSetLength\n offset += 2;\n\n if (len === 0) {\n continue;\n }\n\n // Notice: Nalu without startcode header (00 00 00 01)\n let sps = new Uint8Array(arrayBuffer, dataOffset + offset, len);\n offset += len;\n\n let config = SPSParser.parseSPS(sps);\n if (i !== 0) {\n // ignore other sps's config\n continue;\n }\n\n meta.codecWidth = config.codec_size.width;\n meta.codecHeight = config.codec_size.height;\n meta.presentWidth = config.present_size.width;\n meta.presentHeight = config.present_size.height;\n\n meta.profile = config.profile_string;\n meta.level = config.level_string;\n meta.bitDepth = config.bit_depth;\n meta.chromaFormat = config.chroma_format;\n meta.sarRatio = config.sar_ratio;\n meta.frameRate = config.frame_rate;\n\n if (config.frame_rate.fixed === false ||\n config.frame_rate.fps_num === 0 ||\n config.frame_rate.fps_den === 0) {\n meta.frameRate = this._referenceFrameRate;\n }\n\n let fps_den = meta.frameRate.fps_den;\n let fps_num = meta.frameRate.fps_num;\n meta.refSampleDuration = meta.timescale * (fps_den / fps_num);\n\n let codecArray = sps.subarray(1, 4);\n let codecString = 'avc1.';\n for (let j = 0; j < 3; j++) {\n let h = codecArray[j].toString(16);\n if (h.length < 2) {\n h = '0' + h;\n }\n codecString += h;\n }\n meta.codec = codecString;\n\n let mi = this._mediaInfo;\n mi.width = meta.codecWidth;\n mi.height = meta.codecHeight;\n mi.fps = meta.frameRate.fps;\n mi.profile = meta.profile;\n mi.level = meta.level;\n mi.chromaFormat = config.chroma_format_string;\n mi.sarNum = meta.sarRatio.width;\n mi.sarDen = meta.sarRatio.height;\n mi.videoCodec = codecString;\n\n if (mi.hasAudio) {\n if (mi.audioCodec != null) {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + ',' + mi.audioCodec + '\"';\n }\n } else {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + '\"';\n }\n if (mi.isComplete()) {\n this._onMediaInfo(mi);\n }\n }\n\n let ppsCount = v.getUint8(offset); // numOfPictureParameterSets\n if (ppsCount === 0) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord: No PPS');\n return;\n } else if (ppsCount > 1) {\n Log.w(this.TAG, `Flv: Strange AVCDecoderConfigurationRecord: PPS Count = ${ppsCount}`);\n }\n\n offset++;\n\n for (let i = 0; i < ppsCount; i++) {\n let len = v.getUint16(offset, !le); // pictureParameterSetLength\n offset += 2;\n\n if (len === 0) {\n continue;\n }\n\n // pps is useless for extracting video information\n offset += len;\n }\n\n meta.avcc = new Uint8Array(dataSize);\n meta.avcc.set(new Uint8Array(arrayBuffer, dataOffset, dataSize), 0);\n Log.v(this.TAG, 'Parsed AVCDecoderConfigurationRecord');\n\n if (this._isInitialMetadataDispatched()) {\n // flush parsed frames\n if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {\n this._onDataAvailable(this._audioTrack, this._videoTrack);\n }\n } else {\n this._videoInitialMetadataDispatched = true;\n }\n // notify new metadata\n this._dispatch = false;\n this._onTrackMetadata('video', meta);\n }\n\n _parseAVCVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType, cts) {\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let units = [], length = 0;\n\n let offset = 0;\n const lengthSize = this._naluLengthSize;\n let dts = this._timestampBase + tagTimestamp;\n let keyframe = (frameType === 1); // from FLV Frame Type constants\n\n while (offset < dataSize) {\n if (offset + 4 >= dataSize) {\n Log.w(this.TAG, `Malformed Nalu near timestamp ${dts}, offset = ${offset}, dataSize = ${dataSize}`);\n break; // data not enough for next Nalu\n }\n // Nalu with length-header (AVC1)\n let naluSize = v.getUint32(offset, !le); // Big-Endian read\n if (lengthSize === 3) {\n naluSize >>>= 8;\n }\n if (naluSize > dataSize - lengthSize) {\n Log.w(this.TAG, `Malformed Nalus near timestamp ${dts}, NaluSize > DataSize!`);\n return;\n }\n\n let unitType = v.getUint8(offset + lengthSize) & 0x1F;\n\n if (unitType === 5) { // IDR\n keyframe = true;\n }\n\n let data = new Uint8Array(arrayBuffer, dataOffset + offset, lengthSize + naluSize);\n let unit = {type: unitType, data: data};\n units.push(unit);\n length += data.byteLength;\n\n offset += lengthSize + naluSize;\n }\n\n if (units.length) {\n let track = this._videoTrack;\n let avcSample = {\n units: units,\n length: length,\n isKeyframe: keyframe,\n dts: dts,\n cts: cts,\n pts: (dts + cts)\n };\n if (keyframe) {\n avcSample.fileposition = tagPosition;\n }\n track.samples.push(avcSample);\n track.length += length;\n }\n }\n\n}\n\nexport default FLVDemuxer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport ExpGolomb from './exp-golomb.js';\n\nclass SPSParser {\n\n static _ebsp2rbsp(uint8array) {\n let src = uint8array;\n let src_length = src.byteLength;\n let dst = new Uint8Array(src_length);\n let dst_idx = 0;\n\n for (let i = 0; i < src_length; i++) {\n if (i >= 2) {\n // Unescape: Skip 0x03 after 00 00\n if (src[i] === 0x03 && src[i - 1] === 0x00 && src[i - 2] === 0x00) {\n continue;\n }\n }\n dst[dst_idx] = src[i];\n dst_idx++;\n }\n\n return new Uint8Array(dst.buffer, 0, dst_idx);\n }\n\n static parseSPS(uint8array) {\n let rbsp = SPSParser._ebsp2rbsp(uint8array);\n let gb = new ExpGolomb(rbsp);\n\n gb.readByte();\n let profile_idc = gb.readByte(); // profile_idc\n gb.readByte(); // constraint_set_flags[5] + reserved_zero[3]\n let level_idc = gb.readByte(); // level_idc\n gb.readUEG(); // seq_parameter_set_id\n\n let profile_string = SPSParser.getProfileString(profile_idc);\n let level_string = SPSParser.getLevelString(level_idc);\n let chroma_format_idc = 1;\n let chroma_format = 420;\n let chroma_format_table = [0, 420, 422, 444];\n let bit_depth = 8;\n\n if (profile_idc === 100 || profile_idc === 110 || profile_idc === 122 ||\n profile_idc === 244 || profile_idc === 44 || profile_idc === 83 ||\n profile_idc === 86 || profile_idc === 118 || profile_idc === 128 ||\n profile_idc === 138 || profile_idc === 144) {\n\n chroma_format_idc = gb.readUEG();\n if (chroma_format_idc === 3) {\n gb.readBits(1); // separate_colour_plane_flag\n }\n if (chroma_format_idc <= 3) {\n chroma_format = chroma_format_table[chroma_format_idc];\n }\n\n bit_depth = gb.readUEG() + 8; // bit_depth_luma_minus8\n gb.readUEG(); // bit_depth_chroma_minus8\n gb.readBits(1); // qpprime_y_zero_transform_bypass_flag\n if (gb.readBool()) { // seq_scaling_matrix_present_flag\n let scaling_list_count = (chroma_format_idc !== 3) ? 8 : 12;\n for (let i = 0; i < scaling_list_count; i++) {\n if (gb.readBool()) { // seq_scaling_list_present_flag\n if (i < 6) {\n SPSParser._skipScalingList(gb, 16);\n } else {\n SPSParser._skipScalingList(gb, 64);\n }\n }\n }\n }\n }\n gb.readUEG(); // log2_max_frame_num_minus4\n let pic_order_cnt_type = gb.readUEG();\n if (pic_order_cnt_type === 0) {\n gb.readUEG(); // log2_max_pic_order_cnt_lsb_minus_4\n } else if (pic_order_cnt_type === 1) {\n gb.readBits(1); // delta_pic_order_always_zero_flag\n gb.readSEG(); // offset_for_non_ref_pic\n gb.readSEG(); // offset_for_top_to_bottom_field\n let num_ref_frames_in_pic_order_cnt_cycle = gb.readUEG();\n for (let i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) {\n gb.readSEG(); // offset_for_ref_frame\n }\n }\n gb.readUEG(); // max_num_ref_frames\n gb.readBits(1); // gaps_in_frame_num_value_allowed_flag\n\n let pic_width_in_mbs_minus1 = gb.readUEG();\n let pic_height_in_map_units_minus1 = gb.readUEG();\n\n let frame_mbs_only_flag = gb.readBits(1);\n if (frame_mbs_only_flag === 0) {\n gb.readBits(1); // mb_adaptive_frame_field_flag\n }\n gb.readBits(1); // direct_8x8_inference_flag\n\n let frame_crop_left_offset = 0;\n let frame_crop_right_offset = 0;\n let frame_crop_top_offset = 0;\n let frame_crop_bottom_offset = 0;\n\n let frame_cropping_flag = gb.readBool();\n if (frame_cropping_flag) {\n frame_crop_left_offset = gb.readUEG();\n frame_crop_right_offset = gb.readUEG();\n frame_crop_top_offset = gb.readUEG();\n frame_crop_bottom_offset = gb.readUEG();\n }\n\n let sar_width = 1, sar_height = 1;\n let fps = 0, fps_fixed = true, fps_num = 0, fps_den = 0;\n\n let vui_parameters_present_flag = gb.readBool();\n if (vui_parameters_present_flag) {\n if (gb.readBool()) { // aspect_ratio_info_present_flag\n let aspect_ratio_idc = gb.readByte();\n let sar_w_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2];\n let sar_h_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1];\n\n if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {\n sar_width = sar_w_table[aspect_ratio_idc - 1];\n sar_height = sar_h_table[aspect_ratio_idc - 1];\n } else if (aspect_ratio_idc === 255) {\n sar_width = gb.readByte() << 8 | gb.readByte();\n sar_height = gb.readByte() << 8 | gb.readByte();\n }\n }\n\n if (gb.readBool()) { // overscan_info_present_flag\n gb.readBool(); // overscan_appropriate_flag\n }\n if (gb.readBool()) { // video_signal_type_present_flag\n gb.readBits(4); // video_format & video_full_range_flag\n if (gb.readBool()) { // colour_description_present_flag\n gb.readBits(24); // colour_primaries & transfer_characteristics & matrix_coefficients\n }\n }\n if (gb.readBool()) { // chroma_loc_info_present_flag\n gb.readUEG(); // chroma_sample_loc_type_top_field\n gb.readUEG(); // chroma_sample_loc_type_bottom_field\n }\n if (gb.readBool()) { // timing_info_present_flag\n let num_units_in_tick = gb.readBits(32);\n let time_scale = gb.readBits(32);\n fps_fixed = gb.readBool(); // fixed_frame_rate_flag\n\n fps_num = time_scale;\n fps_den = num_units_in_tick * 2;\n fps = fps_num / fps_den;\n }\n }\n\n let sarScale = 1;\n if (sar_width !== 1 || sar_height !== 1) {\n sarScale = sar_width / sar_height;\n }\n\n let crop_unit_x = 0, crop_unit_y = 0;\n if (chroma_format_idc === 0) {\n crop_unit_x = 1;\n crop_unit_y = 2 - frame_mbs_only_flag;\n } else {\n let sub_wc = (chroma_format_idc === 3) ? 1 : 2;\n let sub_hc = (chroma_format_idc === 1) ? 2 : 1;\n crop_unit_x = sub_wc;\n crop_unit_y = sub_hc * (2 - frame_mbs_only_flag);\n }\n\n let codec_width = (pic_width_in_mbs_minus1 + 1) * 16;\n let codec_height = (2 - frame_mbs_only_flag) * ((pic_height_in_map_units_minus1 + 1) * 16);\n\n codec_width -= (frame_crop_left_offset + frame_crop_right_offset) * crop_unit_x;\n codec_height -= (frame_crop_top_offset + frame_crop_bottom_offset) * crop_unit_y;\n\n let present_width = Math.ceil(codec_width * sarScale);\n\n gb.destroy();\n gb = null;\n\n return {\n profile_string: profile_string, // baseline, high, high10, ...\n level_string: level_string, // 3, 3.1, 4, 4.1, 5, 5.1, ...\n bit_depth: bit_depth, // 8bit, 10bit, ...\n chroma_format: chroma_format, // 4:2:0, 4:2:2, ...\n chroma_format_string: SPSParser.getChromaFormatString(chroma_format),\n\n frame_rate: {\n fixed: fps_fixed,\n fps: fps,\n fps_den: fps_den,\n fps_num: fps_num\n },\n\n sar_ratio: {\n width: sar_width,\n height: sar_height\n },\n\n codec_size: {\n width: codec_width,\n height: codec_height\n },\n\n present_size: {\n width: present_width,\n height: codec_height\n }\n };\n }\n\n static _skipScalingList(gb, count) {\n let last_scale = 8, next_scale = 8;\n let delta_scale = 0;\n for (let i = 0; i < count; i++) {\n if (next_scale !== 0) {\n delta_scale = gb.readSEG();\n next_scale = (last_scale + delta_scale + 256) % 256;\n }\n last_scale = (next_scale === 0) ? last_scale : next_scale;\n }\n }\n\n static getProfileString(profile_idc) {\n switch (profile_idc) {\n case 66:\n return 'Baseline';\n case 77:\n return 'Main';\n case 88:\n return 'Extended';\n case 100:\n return 'High';\n case 110:\n return 'High10';\n case 122:\n return 'High422';\n case 244:\n return 'High444';\n default:\n return 'Unknown';\n }\n }\n\n static getLevelString(level_idc) {\n return (level_idc / 10).toFixed(1);\n }\n\n static getChromaFormatString(chroma) {\n switch (chroma) {\n case 420:\n return '4:2:0';\n case 422:\n return '4:2:2';\n case 444:\n return '4:4:4';\n default:\n return 'Unknown';\n }\n }\n\n}\n\nexport default SPSParser;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Polyfill from './utils/polyfill.js';\nimport Features from './core/features.js';\nimport FlvPlayer from './player/flv-player.js';\nimport NativePlayer from './player/native-player.js';\nimport PlayerEvents from './player/player-events.js';\nimport {ErrorTypes, ErrorDetails} from './player/player-errors.js';\nimport LoggingControl from './utils/logging-control.js';\nimport {InvalidArgumentException} from './utils/exception.js';\n\n// here are all the interfaces\n\n// install polyfills\nPolyfill.install();\n\n\n// factory method\nfunction createPlayer(mediaDataSource, optionalConfig) {\n let mds = mediaDataSource;\n if (mds == null || typeof mds !== 'object') {\n throw new InvalidArgumentException('MediaDataSource must be an javascript object!');\n }\n\n if (!mds.hasOwnProperty('type')) {\n throw new InvalidArgumentException('MediaDataSource must has type field to indicate video file type!');\n }\n\n switch (mds.type) {\n case 'flv':\n return new FlvPlayer(mds, optionalConfig);\n default:\n return new NativePlayer(mds, optionalConfig);\n }\n}\n\n\n// feature detection\nfunction isSupported() {\n return Features.supportMSEH264Playback();\n}\n\nfunction getFeatureList() {\n return Features.getFeatureList();\n}\n\n\n// interfaces\nlet flvjs = {};\n\nflvjs.createPlayer = createPlayer;\nflvjs.isSupported = isSupported;\nflvjs.getFeatureList = getFeatureList;\n\nflvjs.Events = PlayerEvents;\nflvjs.ErrorTypes = ErrorTypes;\nflvjs.ErrorDetails = ErrorDetails;\n\nflvjs.FlvPlayer = FlvPlayer;\nflvjs.NativePlayer = NativePlayer;\nflvjs.LoggingControl = LoggingControl;\n\nObject.defineProperty(flvjs, 'version', {\n enumerable: true,\n get: function () {\n // replaced by browserify-versionify transform\n return '__VERSION__';\n }\n});\n\nexport default flvjs;","// entry/index file\n\n// make it compatible with browserify's umd wrapper\nmodule.exports = require('./flv.js').default;\n","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n/* fetch + stream IO loader. Currently working on chrome 43+.\n * fetch provides a better alternative http API to XMLHttpRequest\n *\n * fetch spec https://fetch.spec.whatwg.org/\n * stream spec https://streams.spec.whatwg.org/\n */\nclass FetchStreamLoader extends BaseLoader {\n\n static isSupported() {\n try {\n // fetch + stream is broken on Microsoft Edge. Disable before build 15048.\n // see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8196907/\n // Fixed in Jan 10, 2017. Build 15048+ removed from blacklist.\n let isWorkWellEdge = Browser.msedge && Browser.version.minor >= 15048;\n let browserNotBlacklisted = Browser.msedge ? isWorkWellEdge : true;\n return (self.fetch && self.ReadableStream && browserNotBlacklisted);\n } catch (e) {\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('fetch-stream-loader');\n this.TAG = 'FetchStreamLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = true;\n\n this._requestAbort = false;\n this._contentLength = null;\n this._receivedLength = 0;\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n super.destroy();\n }\n\n open(dataSource, range) {\n this._dataSource = dataSource;\n this._range = range;\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n\n let headers = new self.Headers();\n\n if (typeof seekConfig.headers === 'object') {\n let configHeaders = seekConfig.headers;\n for (let key in configHeaders) {\n if (configHeaders.hasOwnProperty(key)) {\n headers.append(key, configHeaders[key]);\n }\n }\n }\n\n let params = {\n method: 'GET',\n headers: headers,\n mode: 'cors',\n cache: 'default',\n // The default policy of Fetch API in the whatwg standard\n // Safari incorrectly indicates 'no-referrer' as default policy, fuck it\n referrerPolicy: 'no-referrer-when-downgrade'\n };\n\n // cors is enabled by default\n if (dataSource.cors === false) {\n // no-cors means 'disregard cors policy', which can only be used in ServiceWorker\n params.mode = 'same-origin';\n }\n\n // withCredentials is disabled by default\n if (dataSource.withCredentials) {\n params.credentials = 'include';\n }\n\n // referrerPolicy from config\n if (dataSource.referrerPolicy) {\n params.referrerPolicy = dataSource.referrerPolicy;\n }\n\n this._status = LoaderStatus.kConnecting;\n self.fetch(seekConfig.url, params).then((res) => {\n if (this._requestAbort) {\n this._requestAbort = false;\n this._status = LoaderStatus.kIdle;\n return;\n }\n if (res.ok && (res.status >= 200 && res.status <= 299)) {\n if (res.url !== seekConfig.url) {\n if (this._onURLRedirect) {\n let redirectedURL = this._seekHandler.removeURLParameters(res.url);\n this._onURLRedirect(redirectedURL);\n }\n }\n\n let lengthHeader = res.headers.get('Content-Length');\n if (lengthHeader != null) {\n this._contentLength = parseInt(lengthHeader);\n if (this._contentLength !== 0) {\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n }\n\n return this._pump.call(this, res.body.getReader());\n } else {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: res.status, msg: res.statusText});\n } else {\n throw new RuntimeException('FetchStreamLoader: Http code invalid, ' + res.status + ' ' + res.statusText);\n }\n }\n }).catch((e) => {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, {code: -1, msg: e.message});\n } else {\n throw e;\n }\n });\n }\n\n abort() {\n this._requestAbort = true;\n }\n\n _pump(reader) { // ReadableStreamReader\n return reader.read().then((result) => {\n if (result.done) {\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);\n }\n } else {\n if (this._requestAbort === true) {\n this._requestAbort = false;\n this._status = LoaderStatus.kComplete;\n return reader.cancel();\n }\n\n this._status = LoaderStatus.kBuffering;\n\n let chunk = result.value.buffer;\n let byteStart = this._range.from + this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n\n this._pump(reader);\n }\n }).catch((e) => {\n if (e.code === 11 && Browser.msedge) { // InvalidStateError on Microsoft Edge\n // Workaround: Edge may throw InvalidStateError after ReadableStreamReader.cancel() call\n // Ignore the unknown exception.\n // Related issue: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11265202/\n return;\n }\n\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if ((e.code === 19 || e.message === 'network error') && // NETWORK_ERR\n (this._contentLength === null ||\n (this._contentLength !== null && this._receivedLength < this._contentLength))) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: e.code, msg: 'Fetch stream meet Early-EOF'};\n } else {\n type = LoaderErrors.EXCEPTION;\n info = {code: e.code, msg: e.message};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n });\n }\n\n}\n\nexport default FetchStreamLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport SpeedSampler from './speed-sampler.js';\nimport {LoaderStatus, LoaderErrors} from './loader.js';\nimport FetchStreamLoader from './fetch-stream-loader.js';\nimport MozChunkedLoader from './xhr-moz-chunked-loader.js';\nimport MSStreamLoader from './xhr-msstream-loader.js';\nimport RangeLoader from './xhr-range-loader.js';\nimport WebSocketLoader from './websocket-loader.js';\nimport RangeSeekHandler from './range-seek-handler.js';\nimport ParamSeekHandler from './param-seek-handler.js';\nimport {RuntimeException, IllegalStateException, InvalidArgumentException} from '../utils/exception.js';\n\n/**\n * DataSource: {\n * url: string,\n * filesize: number,\n * cors: boolean,\n * withCredentials: boolean\n * }\n * \n */\n\n// Manage IO Loaders\nclass IOController {\n\n constructor(dataSource, config, extraData) {\n this.TAG = 'IOController';\n\n this._config = config;\n this._extraData = extraData;\n\n this._stashInitialSize = 1024 * 384; // default initial size: 384KB\n if (config.stashInitialSize != undefined && config.stashInitialSize > 0) {\n // apply from config\n this._stashInitialSize = config.stashInitialSize;\n }\n\n this._stashUsed = 0;\n this._stashSize = this._stashInitialSize;\n this._bufferSize = 1024 * 1024 * 3; // initial size: 3MB\n this._stashBuffer = new ArrayBuffer(this._bufferSize);\n this._stashByteStart = 0;\n this._enableStash = true;\n if (config.enableStashBuffer === false) {\n this._enableStash = false;\n }\n\n this._loader = null;\n this._loaderClass = null;\n this._seekHandler = null;\n\n this._dataSource = dataSource;\n this._isWebSocketURL = /wss?:\\/\\/(.+?)/.test(dataSource.url);\n this._refTotalLength = dataSource.filesize ? dataSource.filesize : null;\n this._totalLength = this._refTotalLength;\n this._fullRequestFlag = false;\n this._currentRange = null;\n this._redirectedURL = null;\n\n this._speedNormalized = 0;\n this._speedSampler = new SpeedSampler();\n this._speedNormalizeList = [64, 128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096];\n\n this._isEarlyEofReconnecting = false;\n\n this._paused = false;\n this._resumeFrom = 0;\n\n this._onDataArrival = null;\n this._onSeeked = null;\n this._onError = null;\n this._onComplete = null;\n this._onRedirect = null;\n this._onRecoveredEarlyEof = null;\n\n this._selectSeekHandler();\n this._selectLoader();\n this._createLoader();\n }\n\n destroy() {\n if (this._loader.isWorking()) {\n this._loader.abort();\n }\n this._loader.destroy();\n this._loader = null;\n this._loaderClass = null;\n this._dataSource = null;\n this._stashBuffer = null;\n this._stashUsed = this._stashSize = this._bufferSize = this._stashByteStart = 0;\n this._currentRange = null;\n this._speedSampler = null;\n\n this._isEarlyEofReconnecting = false;\n\n this._onDataArrival = null;\n this._onSeeked = null;\n this._onError = null;\n this._onComplete = null;\n this._onRedirect = null;\n this._onRecoveredEarlyEof = null;\n\n this._extraData = null;\n }\n\n isWorking() {\n return this._loader && this._loader.isWorking() && !this._paused;\n }\n\n isPaused() {\n return this._paused;\n }\n\n get status() {\n return this._loader.status;\n }\n\n get extraData() {\n return this._extraData;\n }\n\n set extraData(data) {\n this._extraData = data;\n }\n\n // prototype: function onDataArrival(chunks: ArrayBuffer, byteStart: number): number\n get onDataArrival() {\n return this._onDataArrival;\n }\n\n set onDataArrival(callback) {\n this._onDataArrival = callback;\n }\n\n get onSeeked() {\n return this._onSeeked;\n }\n\n set onSeeked(callback) {\n this._onSeeked = callback;\n }\n\n // prototype: function onError(type: number, info: {code: number, msg: string}): void\n get onError() {\n return this._onError;\n }\n\n set onError(callback) {\n this._onError = callback;\n }\n\n get onComplete() {\n return this._onComplete;\n }\n\n set onComplete(callback) {\n this._onComplete = callback;\n }\n\n get onRedirect() {\n return this._onRedirect;\n }\n\n set onRedirect(callback) {\n this._onRedirect = callback;\n }\n\n get onRecoveredEarlyEof() {\n return this._onRecoveredEarlyEof;\n }\n\n set onRecoveredEarlyEof(callback) {\n this._onRecoveredEarlyEof = callback;\n }\n\n get currentURL() {\n return this._dataSource.url;\n }\n\n get hasRedirect() {\n return (this._redirectedURL != null || this._dataSource.redirectedURL != undefined);\n }\n\n get currentRedirectedURL() {\n return this._redirectedURL || this._dataSource.redirectedURL;\n }\n\n // in KB/s\n get currentSpeed() {\n if (this._loaderClass === RangeLoader) {\n // SpeedSampler is inaccuracy if loader is RangeLoader\n return this._loader.currentSpeed;\n }\n return this._speedSampler.lastSecondKBps;\n }\n\n get loaderType() {\n return this._loader.type;\n }\n\n _selectSeekHandler() {\n let config = this._config;\n\n if (config.seekType === 'range') {\n this._seekHandler = new RangeSeekHandler(this._config.rangeLoadZeroStart);\n } else if (config.seekType === 'param') {\n let paramStart = config.seekParamStart || 'bstart';\n let paramEnd = config.seekParamEnd || 'bend';\n\n this._seekHandler = new ParamSeekHandler(paramStart, paramEnd);\n } else if (config.seekType === 'custom') {\n if (typeof config.customSeekHandler !== 'function') {\n throw new InvalidArgumentException('Custom seekType specified in config but invalid customSeekHandler!');\n }\n this._seekHandler = new config.customSeekHandler();\n } else {\n throw new InvalidArgumentException(`Invalid seekType in config: ${config.seekType}`);\n }\n }\n\n _selectLoader() {\n if (this._isWebSocketURL) {\n this._loaderClass = WebSocketLoader;\n } else if (FetchStreamLoader.isSupported()) {\n this._loaderClass = FetchStreamLoader;\n } else if (MozChunkedLoader.isSupported()) {\n this._loaderClass = MozChunkedLoader;\n } else if (RangeLoader.isSupported()) {\n this._loaderClass = RangeLoader;\n } else {\n throw new RuntimeException('Your browser doesn\\'t support xhr with arraybuffer responseType!');\n }\n }\n\n _createLoader() {\n this._loader = new this._loaderClass(this._seekHandler, this._config);\n if (this._loader.needStashBuffer === false) {\n this._enableStash = false;\n }\n this._loader.onContentLengthKnown = this._onContentLengthKnown.bind(this);\n this._loader.onURLRedirect = this._onURLRedirect.bind(this);\n this._loader.onDataArrival = this._onLoaderChunkArrival.bind(this);\n this._loader.onComplete = this._onLoaderComplete.bind(this);\n this._loader.onError = this._onLoaderError.bind(this);\n }\n\n open(optionalFrom) {\n this._currentRange = {from: 0, to: -1};\n if (optionalFrom) {\n this._currentRange.from = optionalFrom;\n }\n\n this._speedSampler.reset();\n if (!optionalFrom) {\n this._fullRequestFlag = true;\n }\n\n this._loader.open(this._dataSource, Object.assign({}, this._currentRange));\n }\n\n abort() {\n this._loader.abort();\n\n if (this._paused) {\n this._paused = false;\n this._resumeFrom = 0;\n }\n }\n\n pause() {\n if (this.isWorking()) {\n this._loader.abort();\n\n if (this._stashUsed !== 0) {\n this._resumeFrom = this._stashByteStart;\n this._currentRange.to = this._stashByteStart - 1;\n } else {\n this._resumeFrom = this._currentRange.to + 1;\n }\n this._stashUsed = 0;\n this._stashByteStart = 0;\n this._paused = true;\n }\n }\n\n resume() {\n if (this._paused) {\n this._paused = false;\n let bytes = this._resumeFrom;\n this._resumeFrom = 0;\n this._internalSeek(bytes, true);\n }\n }\n\n seek(bytes) {\n this._paused = false;\n this._stashUsed = 0;\n this._stashByteStart = 0;\n this._internalSeek(bytes, true);\n }\n\n /**\n * When seeking request is from media seeking, unconsumed stash data should be dropped\n * However, stash data shouldn't be dropped if seeking requested from http reconnection\n *\n * @dropUnconsumed: Ignore and discard all unconsumed data in stash buffer\n */\n _internalSeek(bytes, dropUnconsumed) {\n if (this._loader.isWorking()) {\n this._loader.abort();\n }\n\n // dispatch & flush stash buffer before seek\n this._flushStashBuffer(dropUnconsumed);\n\n this._loader.destroy();\n this._loader = null;\n\n let requestRange = {from: bytes, to: -1};\n this._currentRange = {from: requestRange.from, to: -1};\n\n this._speedSampler.reset();\n this._stashSize = this._stashInitialSize;\n this._createLoader();\n this._loader.open(this._dataSource, requestRange);\n\n if (this._onSeeked) {\n this._onSeeked();\n }\n }\n\n updateUrl(url) {\n if (!url || typeof url !== 'string' || url.length === 0) {\n throw new InvalidArgumentException('Url must be a non-empty string!');\n }\n\n this._dataSource.url = url;\n\n // TODO: replace with new url\n }\n\n _expandBuffer(expectedBytes) {\n let bufferNewSize = this._stashSize;\n while (bufferNewSize + 1024 * 1024 * 1 < expectedBytes) {\n bufferNewSize *= 2;\n }\n\n bufferNewSize += 1024 * 1024 * 1; // bufferSize = stashSize + 1MB\n if (bufferNewSize === this._bufferSize) {\n return;\n }\n\n let newBuffer = new ArrayBuffer(bufferNewSize);\n\n if (this._stashUsed > 0) { // copy existing data into new buffer\n let stashOldArray = new Uint8Array(this._stashBuffer, 0, this._stashUsed);\n let stashNewArray = new Uint8Array(newBuffer, 0, bufferNewSize);\n stashNewArray.set(stashOldArray, 0);\n }\n\n this._stashBuffer = newBuffer;\n this._bufferSize = bufferNewSize;\n }\n\n _normalizeSpeed(input) {\n let list = this._speedNormalizeList;\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (input < list[0]) {\n return list[0];\n }\n\n // binary search\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (input >= list[mid] && input < list[mid + 1])) {\n return list[mid];\n } else if (list[mid] < input) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n }\n\n _adjustStashSize(normalized) {\n let stashSizeKB = 0;\n\n if (this._config.isLive) {\n // live stream: always use single normalized speed for size of stashSizeKB\n stashSizeKB = normalized;\n } else {\n if (normalized < 512) {\n stashSizeKB = normalized;\n } else if (normalized >= 512 && normalized <= 1024) {\n stashSizeKB = Math.floor(normalized * 1.5);\n } else {\n stashSizeKB = normalized * 2;\n }\n }\n\n if (stashSizeKB > 8192) {\n stashSizeKB = 8192;\n }\n\n let bufferSize = stashSizeKB * 1024 + 1024 * 1024 * 1; // stashSize + 1MB\n if (this._bufferSize < bufferSize) {\n this._expandBuffer(bufferSize);\n }\n this._stashSize = stashSizeKB * 1024;\n }\n\n _dispatchChunks(chunks, byteStart) {\n this._currentRange.to = byteStart + chunks.byteLength - 1;\n return this._onDataArrival(chunks, byteStart);\n }\n\n _onURLRedirect(redirectedURL) {\n this._redirectedURL = redirectedURL;\n if (this._onRedirect) {\n this._onRedirect(redirectedURL);\n }\n }\n\n _onContentLengthKnown(contentLength) {\n if (contentLength && this._fullRequestFlag) {\n this._totalLength = contentLength;\n this._fullRequestFlag = false;\n }\n }\n\n _onLoaderChunkArrival(chunk, byteStart, receivedLength) {\n if (!this._onDataArrival) {\n throw new IllegalStateException('IOController: No existing consumer (onDataArrival) callback!');\n }\n if (this._paused) {\n return;\n }\n if (this._isEarlyEofReconnecting) {\n // Auto-reconnect for EarlyEof succeed, notify to upper-layer by callback\n this._isEarlyEofReconnecting = false;\n if (this._onRecoveredEarlyEof) {\n this._onRecoveredEarlyEof();\n }\n }\n\n this._speedSampler.addBytes(chunk.byteLength);\n\n // adjust stash buffer size according to network speed dynamically\n let KBps = this._speedSampler.lastSecondKBps;\n if (KBps !== 0) {\n let normalized = this._normalizeSpeed(KBps);\n if (this._speedNormalized !== normalized) {\n this._speedNormalized = normalized;\n this._adjustStashSize(normalized);\n }\n }\n\n if (!this._enableStash) { // disable stash\n if (this._stashUsed === 0) {\n // dispatch chunk directly to consumer;\n // check ret value (consumed bytes) and stash unconsumed to stashBuffer\n let consumed = this._dispatchChunks(chunk, byteStart);\n if (consumed < chunk.byteLength) { // unconsumed data remain.\n let remain = chunk.byteLength - consumed;\n if (remain > this._bufferSize) {\n this._expandBuffer(remain);\n }\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n stashArray.set(new Uint8Array(chunk, consumed), 0);\n this._stashUsed += remain;\n this._stashByteStart = byteStart + consumed;\n }\n } else {\n // else: Merge chunk into stashBuffer, and dispatch stashBuffer to consumer.\n if (this._stashUsed + chunk.byteLength > this._bufferSize) {\n this._expandBuffer(this._stashUsed + chunk.byteLength);\n }\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n stashArray.set(new Uint8Array(chunk), this._stashUsed);\n this._stashUsed += chunk.byteLength;\n let consumed = this._dispatchChunks(this._stashBuffer.slice(0, this._stashUsed), this._stashByteStart);\n if (consumed < this._stashUsed && consumed > 0) { // unconsumed data remain\n let remainArray = new Uint8Array(this._stashBuffer, consumed);\n stashArray.set(remainArray, 0);\n }\n this._stashUsed -= consumed;\n this._stashByteStart += consumed;\n }\n } else { // enable stash\n if (this._stashUsed === 0 && this._stashByteStart === 0) { // seeked? or init chunk?\n // This is the first chunk after seek action\n this._stashByteStart = byteStart;\n }\n if (this._stashUsed + chunk.byteLength <= this._stashSize) {\n // just stash\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._stashSize);\n stashArray.set(new Uint8Array(chunk), this._stashUsed);\n this._stashUsed += chunk.byteLength;\n } else { // stashUsed + chunkSize > stashSize, size limit exceeded\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n if (this._stashUsed > 0) { // There're stash datas in buffer\n // dispatch the whole stashBuffer, and stash remain data\n // then append chunk to stashBuffer (stash)\n let buffer = this._stashBuffer.slice(0, this._stashUsed);\n let consumed = this._dispatchChunks(buffer, this._stashByteStart);\n if (consumed < buffer.byteLength) {\n if (consumed > 0) {\n let remainArray = new Uint8Array(buffer, consumed);\n stashArray.set(remainArray, 0);\n this._stashUsed = remainArray.byteLength;\n this._stashByteStart += consumed;\n }\n } else {\n this._stashUsed = 0;\n this._stashByteStart += consumed;\n }\n if (this._stashUsed + chunk.byteLength > this._bufferSize) {\n this._expandBuffer(this._stashUsed + chunk.byteLength);\n stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n }\n stashArray.set(new Uint8Array(chunk), this._stashUsed);\n this._stashUsed += chunk.byteLength;\n } else { // stash buffer empty, but chunkSize > stashSize (oh, holy shit)\n // dispatch chunk directly and stash remain data\n let consumed = this._dispatchChunks(chunk, byteStart);\n if (consumed < chunk.byteLength) {\n let remain = chunk.byteLength - consumed;\n if (remain > this._bufferSize) {\n this._expandBuffer(remain);\n stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n }\n stashArray.set(new Uint8Array(chunk, consumed), 0);\n this._stashUsed += remain;\n this._stashByteStart = byteStart + consumed;\n }\n }\n }\n }\n }\n\n _flushStashBuffer(dropUnconsumed) {\n if (this._stashUsed > 0) {\n let buffer = this._stashBuffer.slice(0, this._stashUsed);\n let consumed = this._dispatchChunks(buffer, this._stashByteStart);\n let remain = buffer.byteLength - consumed;\n\n if (consumed < buffer.byteLength) {\n if (dropUnconsumed) {\n Log.w(this.TAG, `${remain} bytes unconsumed data remain when flush buffer, dropped`);\n } else {\n if (consumed > 0) {\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n let remainArray = new Uint8Array(buffer, consumed);\n stashArray.set(remainArray, 0);\n this._stashUsed = remainArray.byteLength;\n this._stashByteStart += consumed;\n }\n return 0;\n }\n }\n this._stashUsed = 0;\n this._stashByteStart = 0;\n return remain;\n }\n return 0;\n }\n\n _onLoaderComplete(from, to) {\n // Force-flush stash buffer, and drop unconsumed data\n this._flushStashBuffer(true);\n\n if (this._onComplete) {\n this._onComplete(this._extraData);\n }\n }\n\n _onLoaderError(type, data) {\n Log.e(this.TAG, `Loader error, code = ${data.code}, msg = ${data.msg}`);\n\n this._flushStashBuffer(false);\n\n if (this._isEarlyEofReconnecting) {\n // Auto-reconnect for EarlyEof failed, throw UnrecoverableEarlyEof error to upper-layer\n this._isEarlyEofReconnecting = false;\n type = LoaderErrors.UNRECOVERABLE_EARLY_EOF;\n }\n\n switch (type) {\n case LoaderErrors.EARLY_EOF: {\n if (!this._config.isLive) {\n // Do internal http reconnect if not live stream\n if (this._totalLength) {\n let nextFrom = this._currentRange.to + 1;\n if (nextFrom < this._totalLength) {\n Log.w(this.TAG, 'Connection lost, trying reconnect...');\n this._isEarlyEofReconnecting = true;\n this._internalSeek(nextFrom, false);\n }\n return;\n }\n // else: We don't know totalLength, throw UnrecoverableEarlyEof\n }\n // live stream: throw UnrecoverableEarlyEof error to upper-layer\n type = LoaderErrors.UNRECOVERABLE_EARLY_EOF;\n break;\n }\n case LoaderErrors.UNRECOVERABLE_EARLY_EOF:\n case LoaderErrors.CONNECTING_TIMEOUT:\n case LoaderErrors.HTTP_STATUS_CODE_INVALID:\n case LoaderErrors.EXCEPTION:\n break;\n }\n\n if (this._onError) {\n this._onError(type, data);\n } else {\n throw new RuntimeException('IOException: ' + data.msg);\n }\n }\n\n}\n\nexport default IOController;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {NotImplementedException} from '../utils/exception.js';\n\nexport const LoaderStatus = {\n kIdle: 0,\n kConnecting: 1,\n kBuffering: 2,\n kError: 3,\n kComplete: 4\n};\n\nexport const LoaderErrors = {\n OK: 'OK',\n EXCEPTION: 'Exception',\n HTTP_STATUS_CODE_INVALID: 'HttpStatusCodeInvalid',\n CONNECTING_TIMEOUT: 'ConnectingTimeout',\n EARLY_EOF: 'EarlyEof',\n UNRECOVERABLE_EARLY_EOF: 'UnrecoverableEarlyEof'\n};\n\n/* Loader has callbacks which have following prototypes:\n * function onContentLengthKnown(contentLength: number): void\n * function onURLRedirect(url: string): void\n * function onDataArrival(chunk: ArrayBuffer, byteStart: number, receivedLength: number): void\n * function onError(errorType: number, errorInfo: {code: number, msg: string}): void\n * function onComplete(rangeFrom: number, rangeTo: number): void\n */\nexport class BaseLoader {\n\n constructor(typeName) {\n this._type = typeName || 'undefined';\n this._status = LoaderStatus.kIdle;\n this._needStash = false;\n // callbacks\n this._onContentLengthKnown = null;\n this._onURLRedirect = null;\n this._onDataArrival = null;\n this._onError = null;\n this._onComplete = null;\n }\n\n destroy() {\n this._status = LoaderStatus.kIdle;\n this._onContentLengthKnown = null;\n this._onURLRedirect = null;\n this._onDataArrival = null;\n this._onError = null;\n this._onComplete = null;\n }\n\n isWorking() {\n return this._status === LoaderStatus.kConnecting || this._status === LoaderStatus.kBuffering;\n }\n\n get type() {\n return this._type;\n }\n\n get status() {\n return this._status;\n }\n\n get needStashBuffer() {\n return this._needStash;\n }\n\n get onContentLengthKnown() {\n return this._onContentLengthKnown;\n }\n\n set onContentLengthKnown(callback) {\n this._onContentLengthKnown = callback;\n }\n\n get onURLRedirect() {\n return this._onURLRedirect;\n }\n\n set onURLRedirect(callback) {\n this._onURLRedirect = callback;\n }\n\n get onDataArrival() {\n return this._onDataArrival;\n }\n\n set onDataArrival(callback) {\n this._onDataArrival = callback;\n }\n\n get onError() {\n return this._onError;\n }\n\n set onError(callback) {\n this._onError = callback;\n }\n\n get onComplete() {\n return this._onComplete;\n }\n\n set onComplete(callback) {\n this._onComplete = callback;\n }\n\n // pure virtual\n open(dataSource, range) {\n throw new NotImplementedException('Unimplemented abstract function!');\n }\n\n abort() {\n throw new NotImplementedException('Unimplemented abstract function!');\n }\n\n\n}","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass ParamSeekHandler {\n\n constructor(paramStart, paramEnd) {\n this._startName = paramStart;\n this._endName = paramEnd;\n }\n\n getConfig(baseUrl, range) {\n let url = baseUrl;\n\n if (range.from !== 0 || range.to !== -1) {\n let needAnd = true;\n if (url.indexOf('?') === -1) {\n url += '?';\n needAnd = false;\n }\n\n if (needAnd) {\n url += '&';\n }\n\n url += `${this._startName}=${range.from.toString()}`;\n\n if (range.to !== -1) {\n url += `&${this._endName}=${range.to.toString()}`;\n }\n }\n\n return {\n url: url,\n headers: {}\n };\n }\n\n removeURLParameters(seekedURL) {\n let baseURL = seekedURL.split('?')[0];\n let params = undefined;\n\n let queryIndex = seekedURL.indexOf('?');\n if (queryIndex !== -1) {\n params = seekedURL.substring(queryIndex + 1);\n }\n\n let resultParams = '';\n\n if (params != undefined && params.length > 0) {\n let pairs = params.split('&');\n\n for (let i = 0; i < pairs.length; i++) {\n let pair = pairs[i].split('=');\n let requireAnd = (i > 0);\n\n if (pair[0] !== this._startName && pair[0] !== this._endName) {\n if (requireAnd) {\n resultParams += '&';\n }\n resultParams += pairs[i];\n }\n }\n }\n\n return (resultParams.length === 0) ? baseURL : baseURL + '?' + resultParams;\n }\n\n}\n\nexport default ParamSeekHandler;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass RangeSeekHandler {\n\n constructor(zeroStart) {\n this._zeroStart = zeroStart || false;\n }\n\n getConfig(url, range) {\n let headers = {};\n\n if (range.from !== 0 || range.to !== -1) {\n let param;\n if (range.to !== -1) {\n param = `bytes=${range.from.toString()}-${range.to.toString()}`;\n } else {\n param = `bytes=${range.from.toString()}-`;\n }\n headers['Range'] = param;\n } else if (this._zeroStart) {\n headers['Range'] = 'bytes=0-';\n }\n\n return {\n url: url,\n headers: headers\n };\n }\n\n removeURLParameters(seekedURL) {\n return seekedURL;\n }\n\n}\n\nexport default RangeSeekHandler;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Utility class to calculate realtime network I/O speed\nclass SpeedSampler {\n\n constructor() {\n // milliseconds\n this._firstCheckpoint = 0;\n this._lastCheckpoint = 0;\n this._intervalBytes = 0;\n this._totalBytes = 0;\n this._lastSecondBytes = 0;\n\n // compatibility detection\n if (self.performance && self.performance.now) {\n this._now = self.performance.now.bind(self.performance);\n } else {\n this._now = Date.now;\n }\n }\n\n reset() {\n this._firstCheckpoint = this._lastCheckpoint = 0;\n this._totalBytes = this._intervalBytes = 0;\n this._lastSecondBytes = 0;\n }\n\n addBytes(bytes) {\n if (this._firstCheckpoint === 0) {\n this._firstCheckpoint = this._now();\n this._lastCheckpoint = this._firstCheckpoint;\n this._intervalBytes += bytes;\n this._totalBytes += bytes;\n } else if (this._now() - this._lastCheckpoint < 1000) {\n this._intervalBytes += bytes;\n this._totalBytes += bytes;\n } else { // duration >= 1000\n this._lastSecondBytes = this._intervalBytes;\n this._intervalBytes = bytes;\n this._totalBytes += bytes;\n this._lastCheckpoint = this._now();\n }\n }\n\n get currentKBps() {\n this.addBytes(0);\n\n let durationSeconds = (this._now() - this._lastCheckpoint) / 1000;\n if (durationSeconds == 0) durationSeconds = 1;\n return (this._intervalBytes / durationSeconds) / 1024;\n }\n\n get lastSecondKBps() {\n this.addBytes(0);\n\n if (this._lastSecondBytes !== 0) {\n return this._lastSecondBytes / 1024;\n } else { // lastSecondBytes === 0\n if (this._now() - this._lastCheckpoint >= 500) {\n // if time interval since last checkpoint has exceeded 500ms\n // the speed is nearly accurate\n return this.currentKBps;\n } else {\n // We don't know\n return 0;\n }\n }\n }\n\n get averageKBps() {\n let durationSeconds = (this._now() - this._firstCheckpoint) / 1000;\n return (this._totalBytes / durationSeconds) / 1024;\n }\n\n}\n\nexport default SpeedSampler;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n// For FLV over WebSocket live stream\nclass WebSocketLoader extends BaseLoader {\n\n static isSupported() {\n try {\n return (typeof self.WebSocket !== 'undefined');\n } catch (e) {\n return false;\n }\n }\n\n constructor() {\n super('websocket-loader');\n this.TAG = 'WebSocketLoader';\n\n this._needStash = true;\n\n this._ws = null;\n this._requestAbort = false;\n this._receivedLength = 0;\n }\n\n destroy() {\n if (this._ws) {\n this.abort();\n }\n super.destroy();\n }\n\n open(dataSource) {\n try {\n let ws = this._ws = new self.WebSocket(dataSource.url);\n ws.binaryType = 'arraybuffer';\n ws.onopen = this._onWebSocketOpen.bind(this);\n ws.onclose = this._onWebSocketClose.bind(this);\n ws.onmessage = this._onWebSocketMessage.bind(this);\n ws.onerror = this._onWebSocketError.bind(this);\n\n this._status = LoaderStatus.kConnecting;\n } catch (e) {\n this._status = LoaderStatus.kError;\n\n let info = {code: e.code, msg: e.message};\n\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n }\n\n abort() {\n let ws = this._ws;\n if (ws && (ws.readyState === 0 || ws.readyState === 1)) { // CONNECTING || OPEN\n this._requestAbort = true;\n ws.close();\n }\n\n this._ws = null;\n this._status = LoaderStatus.kComplete;\n }\n\n _onWebSocketOpen(e) {\n this._status = LoaderStatus.kBuffering;\n }\n\n _onWebSocketClose(e) {\n if (this._requestAbort === true) {\n this._requestAbort = false;\n return;\n }\n\n this._status = LoaderStatus.kComplete;\n\n if (this._onComplete) {\n this._onComplete(0, this._receivedLength - 1);\n }\n }\n\n _onWebSocketMessage(e) {\n if (e.data instanceof ArrayBuffer) {\n this._dispatchArrayBuffer(e.data);\n } else if (e.data instanceof Blob) {\n let reader = new FileReader();\n reader.onload = () => {\n this._dispatchArrayBuffer(reader.result);\n };\n reader.readAsArrayBuffer(e.data);\n } else {\n this._status = LoaderStatus.kError;\n let info = {code: -1, msg: 'Unsupported WebSocket message type: ' + e.data.constructor.name};\n\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n }\n\n _dispatchArrayBuffer(arraybuffer) {\n let chunk = arraybuffer;\n let byteStart = this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n }\n\n _onWebSocketError(e) {\n this._status = LoaderStatus.kError;\n\n let info = {\n code: e.code,\n msg: e.message\n };\n\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n}\n\nexport default WebSocketLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n// For FireFox browser which supports `xhr.responseType = 'moz-chunked-arraybuffer'`\nclass MozChunkedLoader extends BaseLoader {\n\n static isSupported() {\n try {\n let xhr = new XMLHttpRequest();\n // Firefox 37- requires .open() to be called before setting responseType\n xhr.open('GET', 'https://example.com', true);\n xhr.responseType = 'moz-chunked-arraybuffer';\n return (xhr.responseType === 'moz-chunked-arraybuffer');\n } catch (e) {\n Log.w('MozChunkedLoader', e.message);\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('xhr-moz-chunked-loader');\n this.TAG = 'MozChunkedLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = true;\n\n this._xhr = null;\n this._requestAbort = false;\n this._contentLength = null;\n this._receivedLength = 0;\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr.onprogress = null;\n this._xhr.onloadend = null;\n this._xhr.onerror = null;\n this._xhr = null;\n }\n super.destroy();\n }\n\n open(dataSource, range) {\n this._dataSource = dataSource;\n this._range = range;\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n this._requestURL = seekConfig.url;\n\n let xhr = this._xhr = new XMLHttpRequest();\n xhr.open('GET', seekConfig.url, true);\n xhr.responseType = 'moz-chunked-arraybuffer';\n xhr.onreadystatechange = this._onReadyStateChange.bind(this);\n xhr.onprogress = this._onProgress.bind(this);\n xhr.onloadend = this._onLoadEnd.bind(this);\n xhr.onerror = this._onXhrError.bind(this);\n\n // cors is auto detected and enabled by xhr\n\n // withCredentials is disabled by default\n if (dataSource.withCredentials && xhr['withCredentials']) {\n xhr.withCredentials = true;\n }\n\n if (typeof seekConfig.headers === 'object') {\n let headers = seekConfig.headers;\n\n for (let key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n }\n\n this._status = LoaderStatus.kConnecting;\n xhr.send();\n }\n\n abort() {\n this._requestAbort = true;\n if (this._xhr) {\n this._xhr.abort();\n }\n this._status = LoaderStatus.kComplete;\n }\n\n _onReadyStateChange(e) {\n let xhr = e.target;\n\n if (xhr.readyState === 2) { // HEADERS_RECEIVED\n if (xhr.responseURL != undefined && xhr.responseURL !== this._requestURL) {\n if (this._onURLRedirect) {\n let redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);\n this._onURLRedirect(redirectedURL);\n }\n }\n\n if (xhr.status !== 0 && (xhr.status < 200 || xhr.status > 299)) {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});\n } else {\n throw new RuntimeException('MozChunkedLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);\n }\n } else {\n this._status = LoaderStatus.kBuffering;\n }\n }\n }\n\n _onProgress(e) {\n if (this._status === LoaderStatus.kError) {\n // Ignore error response\n return;\n }\n\n if (this._contentLength === null) {\n if (e.total !== null && e.total !== 0) {\n this._contentLength = e.total;\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n }\n\n let chunk = e.target.response;\n let byteStart = this._range.from + this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n }\n\n _onLoadEnd(e) {\n if (this._requestAbort === true) {\n this._requestAbort = false;\n return;\n } else if (this._status === LoaderStatus.kError) {\n return;\n }\n\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);\n }\n }\n\n _onXhrError(e) {\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if (this._contentLength && e.loaded < this._contentLength) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: 'Moz-Chunked stream meet Early-Eof'};\n } else {\n type = LoaderErrors.EXCEPTION;\n info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n}\n\nexport default MozChunkedLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n/* Notice: ms-stream may cause IE/Edge browser crash if seek too frequently!!!\n * The browser may crash in wininet.dll. Disable for now.\n *\n * For IE11/Edge browser by microsoft which supports `xhr.responseType = 'ms-stream'`\n * Notice that ms-stream API sucks. The buffer is always expanding along with downloading.\n *\n * We need to abort the xhr if buffer size exceeded limit size (e.g. 16 MiB), then do reconnect.\n * in order to release previous ArrayBuffer to avoid memory leak\n *\n * Otherwise, the ArrayBuffer will increase to a terrible size that equals final file size.\n */\nclass MSStreamLoader extends BaseLoader {\n\n static isSupported() {\n try {\n if (typeof self.MSStream === 'undefined' || typeof self.MSStreamReader === 'undefined') {\n return false;\n }\n\n let xhr = new XMLHttpRequest();\n xhr.open('GET', 'https://example.com', true);\n xhr.responseType = 'ms-stream';\n return (xhr.responseType === 'ms-stream');\n } catch (e) {\n Log.w('MSStreamLoader', e.message);\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('xhr-msstream-loader');\n this.TAG = 'MSStreamLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = true;\n\n this._xhr = null;\n this._reader = null; // MSStreamReader\n\n this._totalRange = null;\n this._currentRange = null;\n\n this._currentRequestURL = null;\n this._currentRedirectedURL = null;\n\n this._contentLength = null;\n this._receivedLength = 0;\n\n this._bufferLimit = 16 * 1024 * 1024; // 16MB\n this._lastTimeBufferSize = 0;\n this._isReconnecting = false;\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n if (this._reader) {\n this._reader.onprogress = null;\n this._reader.onload = null;\n this._reader.onerror = null;\n this._reader = null;\n }\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr = null;\n }\n super.destroy();\n }\n\n open(dataSource, range) {\n this._internalOpen(dataSource, range, false);\n }\n\n _internalOpen(dataSource, range, isSubrange) {\n this._dataSource = dataSource;\n\n if (!isSubrange) {\n this._totalRange = range;\n } else {\n this._currentRange = range;\n }\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL) {\n if (this._currentRedirectedURL != undefined) {\n sourceURL = this._currentRedirectedURL;\n } else if (dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n this._currentRequestURL = seekConfig.url;\n\n let reader = this._reader = new self.MSStreamReader();\n reader.onprogress = this._msrOnProgress.bind(this);\n reader.onload = this._msrOnLoad.bind(this);\n reader.onerror = this._msrOnError.bind(this);\n\n let xhr = this._xhr = new XMLHttpRequest();\n xhr.open('GET', seekConfig.url, true);\n xhr.responseType = 'ms-stream';\n xhr.onreadystatechange = this._xhrOnReadyStateChange.bind(this);\n xhr.onerror = this._xhrOnError.bind(this);\n\n if (dataSource.withCredentials) {\n xhr.withCredentials = true;\n }\n\n if (typeof seekConfig.headers === 'object') {\n let headers = seekConfig.headers;\n\n for (let key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n }\n\n if (this._isReconnecting) {\n this._isReconnecting = false;\n } else {\n this._status = LoaderStatus.kConnecting;\n }\n xhr.send();\n }\n\n abort() {\n this._internalAbort();\n this._status = LoaderStatus.kComplete;\n }\n\n _internalAbort() {\n if (this._reader) {\n if (this._reader.readyState === 1) { // LOADING\n this._reader.abort();\n }\n this._reader.onprogress = null;\n this._reader.onload = null;\n this._reader.onerror = null;\n this._reader = null;\n }\n if (this._xhr) {\n this._xhr.abort();\n this._xhr.onreadystatechange = null;\n this._xhr = null;\n }\n }\n\n _xhrOnReadyStateChange(e) {\n let xhr = e.target;\n\n if (xhr.readyState === 2) { // HEADERS_RECEIVED\n if (xhr.status >= 200 && xhr.status <= 299) {\n this._status = LoaderStatus.kBuffering;\n\n if (xhr.responseURL != undefined) {\n let redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);\n if (xhr.responseURL !== this._currentRequestURL && redirectedURL !== this._currentRedirectedURL) {\n this._currentRedirectedURL = redirectedURL;\n if (this._onURLRedirect) {\n this._onURLRedirect(redirectedURL);\n }\n }\n }\n\n let lengthHeader = xhr.getResponseHeader('Content-Length');\n if (lengthHeader != null && this._contentLength == null) {\n let length = parseInt(lengthHeader);\n if (length > 0) {\n this._contentLength = length;\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n }\n } else {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});\n } else {\n throw new RuntimeException('MSStreamLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);\n }\n }\n } else if (xhr.readyState === 3) { // LOADING\n if (xhr.status >= 200 && xhr.status <= 299) {\n this._status = LoaderStatus.kBuffering;\n\n let msstream = xhr.response;\n this._reader.readAsArrayBuffer(msstream);\n }\n }\n }\n\n _xhrOnError(e) {\n this._status = LoaderStatus.kError;\n let type = LoaderErrors.EXCEPTION;\n let info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n _msrOnProgress(e) {\n let reader = e.target;\n let bigbuffer = reader.result;\n if (bigbuffer == null) { // result may be null, workaround for buggy M$\n this._doReconnectIfNeeded();\n return;\n }\n\n let slice = bigbuffer.slice(this._lastTimeBufferSize);\n this._lastTimeBufferSize = bigbuffer.byteLength;\n let byteStart = this._totalRange.from + this._receivedLength;\n this._receivedLength += slice.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(slice, byteStart, this._receivedLength);\n }\n\n if (bigbuffer.byteLength >= this._bufferLimit) {\n Log.v(this.TAG, `MSStream buffer exceeded max size near ${byteStart + slice.byteLength}, reconnecting...`);\n this._doReconnectIfNeeded();\n }\n }\n\n _doReconnectIfNeeded() {\n if (this._contentLength == null || this._receivedLength < this._contentLength) {\n this._isReconnecting = true;\n this._lastTimeBufferSize = 0;\n this._internalAbort();\n\n let range = {\n from: this._totalRange.from + this._receivedLength,\n to: -1\n };\n this._internalOpen(this._dataSource, range, true);\n }\n }\n\n _msrOnLoad(e) { // actually it is onComplete event\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._totalRange.from, this._totalRange.from + this._receivedLength - 1);\n }\n }\n\n _msrOnError(e) {\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if (this._contentLength && this._receivedLength < this._contentLength) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: 'MSStream meet Early-Eof'};\n } else {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n}\n\nexport default MSStreamLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport SpeedSampler from './speed-sampler.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n// Universal IO Loader, implemented by adding Range header in xhr's request header\nclass RangeLoader extends BaseLoader {\n\n static isSupported() {\n try {\n let xhr = new XMLHttpRequest();\n xhr.open('GET', 'https://example.com', true);\n xhr.responseType = 'arraybuffer';\n return (xhr.responseType === 'arraybuffer');\n } catch (e) {\n Log.w('RangeLoader', e.message);\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('xhr-range-loader');\n this.TAG = 'RangeLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = false;\n\n this._chunkSizeKBList = [\n 128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192\n ];\n this._currentChunkSizeKB = 384;\n this._currentSpeedNormalized = 0;\n this._zeroSpeedChunkCount = 0;\n\n this._xhr = null;\n this._speedSampler = new SpeedSampler();\n\n this._requestAbort = false;\n this._waitForTotalLength = false;\n this._totalLengthReceived = false;\n\n this._currentRequestURL = null;\n this._currentRedirectedURL = null;\n this._currentRequestRange = null;\n this._totalLength = null; // size of the entire file\n this._contentLength = null; // Content-Length of entire request range\n this._receivedLength = 0; // total received bytes\n this._lastTimeLoaded = 0; // received bytes of current request sub-range\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr.onprogress = null;\n this._xhr.onload = null;\n this._xhr.onerror = null;\n this._xhr = null;\n }\n super.destroy();\n }\n\n get currentSpeed() {\n return this._speedSampler.lastSecondKBps;\n }\n\n open(dataSource, range) {\n this._dataSource = dataSource;\n this._range = range;\n this._status = LoaderStatus.kConnecting;\n\n let useRefTotalLength = false;\n if (this._dataSource.filesize != undefined && this._dataSource.filesize !== 0) {\n useRefTotalLength = true;\n this._totalLength = this._dataSource.filesize;\n }\n\n if (!this._totalLengthReceived && !useRefTotalLength) {\n // We need total filesize\n this._waitForTotalLength = true;\n this._internalOpen(this._dataSource, {from: 0, to: -1});\n } else {\n // We have filesize, start loading\n this._openSubRange();\n }\n }\n\n _openSubRange() {\n let chunkSize = this._currentChunkSizeKB * 1024;\n\n let from = this._range.from + this._receivedLength;\n let to = from + chunkSize;\n\n if (this._contentLength != null) {\n if (to - this._range.from >= this._contentLength) {\n to = this._range.from + this._contentLength - 1;\n }\n }\n\n this._currentRequestRange = {from, to};\n this._internalOpen(this._dataSource, this._currentRequestRange);\n }\n\n _internalOpen(dataSource, range) {\n this._lastTimeLoaded = 0;\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL) {\n if (this._currentRedirectedURL != undefined) {\n sourceURL = this._currentRedirectedURL;\n } else if (dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n this._currentRequestURL = seekConfig.url;\n\n let xhr = this._xhr = new XMLHttpRequest();\n xhr.open('GET', seekConfig.url, true);\n xhr.responseType = 'arraybuffer';\n xhr.onreadystatechange = this._onReadyStateChange.bind(this);\n xhr.onprogress = this._onProgress.bind(this);\n xhr.onload = this._onLoad.bind(this);\n xhr.onerror = this._onXhrError.bind(this);\n\n if (dataSource.withCredentials && xhr['withCredentials']) {\n xhr.withCredentials = true;\n }\n\n if (typeof seekConfig.headers === 'object') {\n let headers = seekConfig.headers;\n\n for (let key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n }\n\n xhr.send();\n }\n\n abort() {\n this._requestAbort = true;\n this._internalAbort();\n this._status = LoaderStatus.kComplete;\n }\n\n _internalAbort() {\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr.onprogress = null;\n this._xhr.onload = null;\n this._xhr.onerror = null;\n this._xhr.abort();\n this._xhr = null;\n }\n }\n\n _onReadyStateChange(e) {\n let xhr = e.target;\n\n if (xhr.readyState === 2) { // HEADERS_RECEIVED\n if (xhr.responseURL != undefined) { // if the browser support this property\n let redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);\n if (xhr.responseURL !== this._currentRequestURL && redirectedURL !== this._currentRedirectedURL) {\n this._currentRedirectedURL = redirectedURL;\n if (this._onURLRedirect) {\n this._onURLRedirect(redirectedURL);\n }\n }\n }\n\n if ((xhr.status >= 200 && xhr.status <= 299)) {\n if (this._waitForTotalLength) {\n return;\n }\n this._status = LoaderStatus.kBuffering;\n } else {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});\n } else {\n throw new RuntimeException('RangeLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);\n }\n }\n }\n }\n\n _onProgress(e) {\n if (this._status === LoaderStatus.kError) {\n // Ignore error response\n return;\n }\n\n if (this._contentLength === null) {\n let openNextRange = false;\n\n if (this._waitForTotalLength) {\n this._waitForTotalLength = false;\n this._totalLengthReceived = true;\n openNextRange = true;\n\n let total = e.total;\n this._internalAbort();\n if (total != null & total !== 0) {\n this._totalLength = total;\n }\n }\n\n // calculate currrent request range's contentLength\n if (this._range.to === -1) {\n this._contentLength = this._totalLength - this._range.from;\n } else { // to !== -1\n this._contentLength = this._range.to - this._range.from + 1;\n }\n\n if (openNextRange) {\n this._openSubRange();\n return;\n }\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n\n let delta = e.loaded - this._lastTimeLoaded;\n this._lastTimeLoaded = e.loaded;\n this._speedSampler.addBytes(delta);\n }\n\n _normalizeSpeed(input) {\n let list = this._chunkSizeKBList;\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (input < list[0]) {\n return list[0];\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (input >= list[mid] && input < list[mid + 1])) {\n return list[mid];\n } else if (list[mid] < input) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n }\n\n _onLoad(e) {\n if (this._status === LoaderStatus.kError) {\n // Ignore error response\n return;\n }\n\n if (this._waitForTotalLength) {\n this._waitForTotalLength = false;\n return;\n }\n\n this._lastTimeLoaded = 0;\n let KBps = this._speedSampler.lastSecondKBps;\n if (KBps === 0) {\n this._zeroSpeedChunkCount++;\n if (this._zeroSpeedChunkCount >= 3) {\n // Try get currentKBps after 3 chunks\n KBps = this._speedSampler.currentKBps;\n }\n }\n\n if (KBps !== 0) {\n let normalized = this._normalizeSpeed(KBps);\n if (this._currentSpeedNormalized !== normalized) {\n this._currentSpeedNormalized = normalized;\n this._currentChunkSizeKB = normalized;\n }\n }\n\n let chunk = e.target.response;\n let byteStart = this._range.from + this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n let reportComplete = false;\n\n if (this._contentLength != null && this._receivedLength < this._contentLength) {\n // continue load next chunk\n this._openSubRange();\n } else {\n reportComplete = true;\n }\n\n // dispatch received chunk\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n\n if (reportComplete) {\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);\n }\n }\n }\n\n _onXhrError(e) {\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if (this._contentLength && this._receivedLength > 0\n && this._receivedLength < this._contentLength) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: 'RangeLoader meet Early-Eof'};\n } else {\n type = LoaderErrors.EXCEPTION;\n info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n}\n\nexport default RangeLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport PlayerEvents from './player-events.js';\nimport Transmuxer from '../core/transmuxer.js';\nimport TransmuxingEvents from '../core/transmuxing-events.js';\nimport MSEController from '../core/mse-controller.js';\nimport MSEEvents from '../core/mse-events.js';\nimport {ErrorTypes, ErrorDetails} from './player-errors.js';\nimport {createDefaultConfig} from '../config.js';\nimport {InvalidArgumentException, IllegalStateException} from '../utils/exception.js';\n\nclass FlvPlayer {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'FlvPlayer';\n this._type = 'FlvPlayer';\n this._emitter = new EventEmitter();\n\n this._config = createDefaultConfig();\n if (typeof config === 'object') {\n Object.assign(this._config, config);\n }\n\n if (mediaDataSource.type.toLowerCase() !== 'flv') {\n throw new InvalidArgumentException('FlvPlayer requires an flv MediaDataSource input!');\n }\n\n if (mediaDataSource.isLive === true) {\n this._config.isLive = true;\n }\n\n this.e = {\n onvLoadedMetadata: this._onvLoadedMetadata.bind(this),\n onvSeeking: this._onvSeeking.bind(this),\n onvCanPlay: this._onvCanPlay.bind(this),\n onvStalled: this._onvStalled.bind(this),\n onvProgress: this._onvProgress.bind(this)\n };\n\n if (self.performance && self.performance.now) {\n this._now = self.performance.now.bind(self.performance);\n } else {\n this._now = Date.now;\n }\n\n this._pendingSeekTime = null; // in seconds\n this._requestSetTime = false;\n this._seekpointRecord = null;\n this._progressChecker = null;\n\n this._mediaDataSource = mediaDataSource;\n this._mediaElement = null;\n this._msectl = null;\n this._transmuxer = null;\n\n this._mseSourceOpened = false;\n this._hasPendingLoad = false;\n this._receivedCanPlay = false;\n\n this._mediaInfo = null;\n this._statisticsInfo = null;\n\n let chromeNeedIDRFix = (Browser.chrome &&\n (Browser.version.major < 50 ||\n (Browser.version.major === 50 && Browser.version.build < 2661)));\n this._alwaysSeekKeyframe = (chromeNeedIDRFix || Browser.msedge || Browser.msie) ? true : false;\n\n if (this._alwaysSeekKeyframe) {\n this._config.accurateSeek = false;\n }\n }\n\n destroy() {\n if (this._progressChecker != null) {\n window.clearInterval(this._progressChecker);\n this._progressChecker = null;\n }\n if (this._transmuxer) {\n this.unload();\n }\n if (this._mediaElement) {\n this.detachMediaElement();\n }\n this.e = null;\n this._mediaDataSource = null;\n\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n if (event === PlayerEvents.MEDIA_INFO) {\n if (this._mediaInfo != null) {\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.MEDIA_INFO, this.mediaInfo);\n });\n }\n } else if (event === PlayerEvents.STATISTICS_INFO) {\n if (this._statisticsInfo != null) {\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, this.statisticsInfo);\n });\n }\n }\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n attachMediaElement(mediaElement) {\n this._mediaElement = mediaElement;\n mediaElement.addEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n mediaElement.addEventListener('seeking', this.e.onvSeeking);\n mediaElement.addEventListener('canplay', this.e.onvCanPlay);\n mediaElement.addEventListener('stalled', this.e.onvStalled);\n mediaElement.addEventListener('progress', this.e.onvProgress);\n\n this._msectl = new MSEController(this._config);\n\n this._msectl.on(MSEEvents.UPDATE_END, this._onmseUpdateEnd.bind(this));\n this._msectl.on(MSEEvents.BUFFER_FULL, this._onmseBufferFull.bind(this));\n this._msectl.on(MSEEvents.SOURCE_OPEN, () => {\n this._mseSourceOpened = true;\n if (this._hasPendingLoad) {\n this._hasPendingLoad = false;\n this.load();\n }\n });\n this._msectl.on(MSEEvents.ERROR, (info) => {\n this._emitter.emit(PlayerEvents.ERROR,\n ErrorTypes.MEDIA_ERROR,\n ErrorDetails.MEDIA_MSE_ERROR,\n info\n );\n });\n\n this._msectl.attachMediaElement(mediaElement);\n\n if (this._pendingSeekTime != null) {\n try {\n mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n } catch (e) {\n // IE11 may throw InvalidStateError if readyState === 0\n // We can defer set currentTime operation after loadedmetadata\n }\n }\n }\n\n detachMediaElement() {\n if (this._mediaElement) {\n this._msectl.detachMediaElement();\n this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n this._mediaElement.removeEventListener('seeking', this.e.onvSeeking);\n this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);\n this._mediaElement.removeEventListener('stalled', this.e.onvStalled);\n this._mediaElement.removeEventListener('progress', this.e.onvProgress);\n this._mediaElement = null;\n }\n if (this._msectl) {\n this._msectl.destroy();\n this._msectl = null;\n }\n }\n\n load() {\n if (!this._mediaElement) {\n throw new IllegalStateException('HTMLMediaElement must be attached before load()!');\n }\n if (this._transmuxer) {\n throw new IllegalStateException('FlvPlayer.load() has been called, please call unload() first!');\n }\n if (this._hasPendingLoad) {\n return;\n }\n\n if (this._config.deferLoadAfterSourceOpen && this._mseSourceOpened === false) {\n this._hasPendingLoad = true;\n return;\n }\n\n if (this._mediaElement.readyState > 0) {\n this._requestSetTime = true;\n // IE11 may throw InvalidStateError if readyState === 0\n this._mediaElement.currentTime = 0;\n }\n\n this._transmuxer = new Transmuxer(this._mediaDataSource, this._config);\n\n this._transmuxer.on(TransmuxingEvents.INIT_SEGMENT, (type, is) => {\n this._msectl.appendInitSegment(is);\n });\n this._transmuxer.on(TransmuxingEvents.MEDIA_SEGMENT, (type, ms) => {\n this._msectl.appendMediaSegment(ms);\n\n // lazyLoad check\n if (this._config.lazyLoad && !this._config.isLive) {\n let currentTime = this._mediaElement.currentTime;\n if (ms.info.endDts >= (currentTime + this._config.lazyLoadMaxDuration) * 1000) {\n if (this._progressChecker == null) {\n Log.v(this.TAG, 'Maximum buffering duration exceeded, suspend transmuxing task');\n this._suspendTransmuxer();\n }\n }\n }\n });\n this._transmuxer.on(TransmuxingEvents.LOADING_COMPLETE, () => {\n this._msectl.endOfStream();\n this._emitter.emit(PlayerEvents.LOADING_COMPLETE);\n });\n this._transmuxer.on(TransmuxingEvents.RECOVERED_EARLY_EOF, () => {\n this._emitter.emit(PlayerEvents.RECOVERED_EARLY_EOF);\n });\n this._transmuxer.on(TransmuxingEvents.IO_ERROR, (detail, info) => {\n this._emitter.emit(PlayerEvents.ERROR, ErrorTypes.NETWORK_ERROR, detail, info);\n });\n this._transmuxer.on(TransmuxingEvents.DEMUX_ERROR, (detail, info) => {\n this._emitter.emit(PlayerEvents.ERROR, ErrorTypes.MEDIA_ERROR, detail, {code: -1, msg: info});\n });\n this._transmuxer.on(TransmuxingEvents.MEDIA_INFO, (mediaInfo) => {\n this._mediaInfo = mediaInfo;\n this._emitter.emit(PlayerEvents.MEDIA_INFO, Object.assign({}, mediaInfo));\n });\n this._transmuxer.on(TransmuxingEvents.STATISTICS_INFO, (statInfo) => {\n this._statisticsInfo = this._fillStatisticsInfo(statInfo);\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, Object.assign({}, this._statisticsInfo));\n });\n this._transmuxer.on(TransmuxingEvents.RECOMMEND_SEEKPOINT, (milliseconds) => {\n if (this._mediaElement && !this._config.accurateSeek) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = milliseconds / 1000;\n }\n });\n\n this._transmuxer.open();\n }\n\n unload() {\n if (this._mediaElement) {\n this._mediaElement.pause();\n }\n if (this._msectl) {\n this._msectl.seek(0);\n }\n if (this._transmuxer) {\n this._transmuxer.close();\n this._transmuxer.destroy();\n this._transmuxer = null;\n }\n }\n\n play() {\n return this._mediaElement.play();\n }\n\n pause() {\n this._mediaElement.pause();\n }\n\n get type() {\n return this._type;\n }\n\n get buffered() {\n return this._mediaElement.buffered;\n }\n\n get duration() {\n return this._mediaElement.duration;\n }\n\n get volume() {\n return this._mediaElement.volume;\n }\n\n set volume(value) {\n this._mediaElement.volume = value;\n }\n\n get muted() {\n return this._mediaElement.muted;\n }\n\n set muted(muted) {\n this._mediaElement.muted = muted;\n }\n\n get currentTime() {\n if (this._mediaElement) {\n return this._mediaElement.currentTime;\n }\n return 0;\n }\n\n set currentTime(seconds) {\n if (this._mediaElement) {\n this._internalSeek(seconds);\n } else {\n this._pendingSeekTime = seconds;\n }\n }\n\n get mediaInfo() {\n return Object.assign({}, this._mediaInfo);\n }\n\n get statisticsInfo() {\n if (this._statisticsInfo == null) {\n this._statisticsInfo = {};\n }\n this._statisticsInfo = this._fillStatisticsInfo(this._statisticsInfo);\n return Object.assign({}, this._statisticsInfo);\n }\n\n _fillStatisticsInfo(statInfo) {\n statInfo.playerType = this._type;\n\n if (!(this._mediaElement instanceof HTMLVideoElement)) {\n return statInfo;\n }\n\n let hasQualityInfo = true;\n let decoded = 0;\n let dropped = 0;\n\n if (this._mediaElement.getVideoPlaybackQuality) {\n let quality = this._mediaElement.getVideoPlaybackQuality();\n decoded = quality.totalVideoFrames;\n dropped = quality.droppedVideoFrames;\n } else if (this._mediaElement.webkitDecodedFrameCount != undefined) {\n decoded = this._mediaElement.webkitDecodedFrameCount;\n dropped = this._mediaElement.webkitDroppedFrameCount;\n } else {\n hasQualityInfo = false;\n }\n\n if (hasQualityInfo) {\n statInfo.decodedFrames = decoded;\n statInfo.droppedFrames = dropped;\n }\n\n return statInfo;\n }\n\n _onmseUpdateEnd() {\n if (!this._config.lazyLoad || this._config.isLive) {\n return;\n }\n\n let buffered = this._mediaElement.buffered;\n let currentTime = this._mediaElement.currentTime;\n let currentRangeStart = 0;\n let currentRangeEnd = 0;\n\n for (let i = 0; i < buffered.length; i++) {\n let start = buffered.start(i);\n let end = buffered.end(i);\n if (start <= currentTime && currentTime < end) {\n currentRangeStart = start;\n currentRangeEnd = end;\n break;\n }\n }\n\n if (currentRangeEnd >= currentTime + this._config.lazyLoadMaxDuration && this._progressChecker == null) {\n Log.v(this.TAG, 'Maximum buffering duration exceeded, suspend transmuxing task');\n this._suspendTransmuxer();\n }\n }\n\n _onmseBufferFull() {\n Log.v(this.TAG, 'MSE SourceBuffer is full, suspend transmuxing task');\n if (this._progressChecker == null) {\n this._suspendTransmuxer();\n }\n }\n\n _suspendTransmuxer() {\n if (this._transmuxer) {\n this._transmuxer.pause();\n\n if (this._progressChecker == null) {\n this._progressChecker = window.setInterval(this._checkProgressAndResume.bind(this), 1000);\n }\n }\n }\n\n _checkProgressAndResume() {\n let currentTime = this._mediaElement.currentTime;\n let buffered = this._mediaElement.buffered;\n\n let needResume = false;\n\n for (let i = 0; i < buffered.length; i++) {\n let from = buffered.start(i);\n let to = buffered.end(i);\n if (currentTime >= from && currentTime < to) {\n if (currentTime >= to - this._config.lazyLoadRecoverDuration) {\n needResume = true;\n }\n break;\n }\n }\n\n if (needResume) {\n window.clearInterval(this._progressChecker);\n this._progressChecker = null;\n if (needResume) {\n Log.v(this.TAG, 'Continue loading from paused position');\n this._transmuxer.resume();\n }\n }\n }\n\n _isTimepointBuffered(seconds) {\n let buffered = this._mediaElement.buffered;\n\n for (let i = 0; i < buffered.length; i++) {\n let from = buffered.start(i);\n let to = buffered.end(i);\n if (seconds >= from && seconds < to) {\n return true;\n }\n }\n return false;\n }\n\n _internalSeek(seconds) {\n let directSeek = this._isTimepointBuffered(seconds);\n\n let directSeekBegin = false;\n let directSeekBeginTime = 0;\n\n if (seconds < 1.0 && this._mediaElement.buffered.length > 0) {\n let videoBeginTime = this._mediaElement.buffered.start(0);\n if ((videoBeginTime < 1.0 && seconds < videoBeginTime) || Browser.safari) {\n directSeekBegin = true;\n // also workaround for Safari: Seek to 0 may cause video stuck, use 0.1 to avoid\n directSeekBeginTime = Browser.safari ? 0.1 : videoBeginTime;\n }\n }\n\n if (directSeekBegin) { // seek to video begin, set currentTime directly if beginPTS buffered\n this._requestSetTime = true;\n this._mediaElement.currentTime = directSeekBeginTime;\n } else if (directSeek) { // buffered position\n if (!this._alwaysSeekKeyframe) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = seconds;\n } else {\n let idr = this._msectl.getNearestKeyframe(Math.floor(seconds * 1000));\n this._requestSetTime = true;\n if (idr != null) {\n this._mediaElement.currentTime = idr.dts / 1000;\n } else {\n this._mediaElement.currentTime = seconds;\n }\n }\n if (this._progressChecker != null) {\n this._checkProgressAndResume();\n }\n } else {\n if (this._progressChecker != null) {\n window.clearInterval(this._progressChecker);\n this._progressChecker = null;\n }\n this._msectl.seek(seconds);\n this._transmuxer.seek(Math.floor(seconds * 1000)); // in milliseconds\n // no need to set mediaElement.currentTime if non-accurateSeek,\n // just wait for the recommend_seekpoint callback\n if (this._config.accurateSeek) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = seconds;\n }\n }\n }\n\n _checkAndApplyUnbufferedSeekpoint() {\n if (this._seekpointRecord) {\n if (this._seekpointRecord.recordTime <= this._now() - 100) {\n let target = this._mediaElement.currentTime;\n this._seekpointRecord = null;\n if (!this._isTimepointBuffered(target)) {\n if (this._progressChecker != null) {\n window.clearTimeout(this._progressChecker);\n this._progressChecker = null;\n }\n // .currentTime is consists with .buffered timestamp\n // Chrome/Edge use DTS, while FireFox/Safari use PTS\n this._msectl.seek(target);\n this._transmuxer.seek(Math.floor(target * 1000));\n // set currentTime if accurateSeek, or wait for recommend_seekpoint callback\n if (this._config.accurateSeek) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = target;\n }\n }\n } else {\n window.setTimeout(this._checkAndApplyUnbufferedSeekpoint.bind(this), 50);\n }\n }\n }\n\n _checkAndResumeStuckPlayback(stalled) {\n let media = this._mediaElement;\n if (stalled || !this._receivedCanPlay || media.readyState < 2) { // HAVE_CURRENT_DATA\n let buffered = media.buffered;\n if (buffered.length > 0 && media.currentTime < buffered.start(0)) {\n Log.w(this.TAG, `Playback seems stuck at ${media.currentTime}, seek to ${buffered.start(0)}`);\n this._requestSetTime = true;\n this._mediaElement.currentTime = buffered.start(0);\n this._mediaElement.removeEventListener('progress', this.e.onvProgress);\n }\n } else {\n // Playback didn't stuck, remove progress event listener\n this._mediaElement.removeEventListener('progress', this.e.onvProgress);\n }\n }\n\n _onvLoadedMetadata(e) {\n if (this._pendingSeekTime != null) {\n this._mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n }\n }\n\n _onvSeeking(e) { // handle seeking request from browser's progress bar\n let target = this._mediaElement.currentTime;\n let buffered = this._mediaElement.buffered;\n\n if (this._requestSetTime) {\n this._requestSetTime = false;\n return;\n }\n\n if (target < 1.0 && buffered.length > 0) {\n // seek to video begin, set currentTime directly if beginPTS buffered\n let videoBeginTime = buffered.start(0);\n if ((videoBeginTime < 1.0 && target < videoBeginTime) || Browser.safari) {\n this._requestSetTime = true;\n // also workaround for Safari: Seek to 0 may cause video stuck, use 0.1 to avoid\n this._mediaElement.currentTime = Browser.safari ? 0.1 : videoBeginTime;\n return;\n }\n }\n\n if (this._isTimepointBuffered(target)) {\n if (this._alwaysSeekKeyframe) {\n let idr = this._msectl.getNearestKeyframe(Math.floor(target * 1000));\n if (idr != null) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = idr.dts / 1000;\n }\n }\n if (this._progressChecker != null) {\n this._checkProgressAndResume();\n }\n return;\n }\n\n this._seekpointRecord = {\n seekPoint: target,\n recordTime: this._now()\n };\n window.setTimeout(this._checkAndApplyUnbufferedSeekpoint.bind(this), 50);\n }\n\n _onvCanPlay(e) {\n this._receivedCanPlay = true;\n this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);\n }\n\n _onvStalled(e) {\n this._checkAndResumeStuckPlayback(true);\n }\n\n _onvProgress(e) {\n this._checkAndResumeStuckPlayback();\n }\n\n}\n\nexport default FlvPlayer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport PlayerEvents from './player-events.js';\nimport {createDefaultConfig} from '../config.js';\nimport {InvalidArgumentException, IllegalStateException} from '../utils/exception.js';\n\n// Player wrapper for browser's native player (HTMLVideoElement) without MediaSource src. \nclass NativePlayer {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'NativePlayer';\n this._type = 'NativePlayer';\n this._emitter = new EventEmitter();\n\n this._config = createDefaultConfig();\n if (typeof config === 'object') {\n Object.assign(this._config, config);\n }\n\n if (mediaDataSource.type.toLowerCase() === 'flv') {\n throw new InvalidArgumentException('NativePlayer does\\'t support flv MediaDataSource input!');\n }\n if (mediaDataSource.hasOwnProperty('segments')) {\n throw new InvalidArgumentException(`NativePlayer(${mediaDataSource.type}) doesn't support multipart playback!`);\n }\n\n this.e = {\n onvLoadedMetadata: this._onvLoadedMetadata.bind(this)\n };\n\n this._pendingSeekTime = null;\n this._statisticsReporter = null;\n\n this._mediaDataSource = mediaDataSource;\n this._mediaElement = null;\n }\n\n destroy() {\n if (this._mediaElement) {\n this.unload();\n this.detachMediaElement();\n }\n this.e = null;\n this._mediaDataSource = null;\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n if (event === PlayerEvents.MEDIA_INFO) {\n if (this._mediaElement != null && this._mediaElement.readyState !== 0) { // HAVE_NOTHING\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.MEDIA_INFO, this.mediaInfo);\n });\n }\n } else if (event === PlayerEvents.STATISTICS_INFO) {\n if (this._mediaElement != null && this._mediaElement.readyState !== 0) {\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, this.statisticsInfo);\n });\n }\n }\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n attachMediaElement(mediaElement) {\n this._mediaElement = mediaElement;\n mediaElement.addEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n\n if (this._pendingSeekTime != null) {\n try {\n mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n } catch (e) {\n // IE11 may throw InvalidStateError if readyState === 0\n // Defer set currentTime operation after loadedmetadata\n }\n }\n }\n\n detachMediaElement() {\n if (this._mediaElement) {\n this._mediaElement.src = '';\n this._mediaElement.removeAttribute('src');\n this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n this._mediaElement = null;\n }\n if (this._statisticsReporter != null) {\n window.clearInterval(this._statisticsReporter);\n this._statisticsReporter = null;\n }\n }\n\n load() {\n if (!this._mediaElement) {\n throw new IllegalStateException('HTMLMediaElement must be attached before load()!');\n }\n this._mediaElement.src = this._mediaDataSource.url;\n\n if (this._mediaElement.readyState > 0) {\n this._mediaElement.currentTime = 0;\n }\n\n this._mediaElement.preload = 'auto';\n this._mediaElement.load();\n this._statisticsReporter = window.setInterval(\n this._reportStatisticsInfo.bind(this),\n this._config.statisticsInfoReportInterval);\n }\n\n unload() {\n if (this._mediaElement) {\n this._mediaElement.src = '';\n this._mediaElement.removeAttribute('src');\n }\n if (this._statisticsReporter != null) {\n window.clearInterval(this._statisticsReporter);\n this._statisticsReporter = null;\n }\n }\n\n play() {\n return this._mediaElement.play();\n }\n\n pause() {\n this._mediaElement.pause();\n }\n\n get type() {\n return this._type;\n }\n\n get buffered() {\n return this._mediaElement.buffered;\n }\n\n get duration() {\n return this._mediaElement.duration;\n }\n\n get volume() {\n return this._mediaElement.volume;\n }\n\n set volume(value) {\n this._mediaElement.volume = value;\n }\n\n get muted() {\n return this._mediaElement.muted;\n }\n\n set muted(muted) {\n this._mediaElement.muted = muted;\n }\n\n get currentTime() {\n if (this._mediaElement) {\n return this._mediaElement.currentTime;\n }\n return 0;\n }\n\n set currentTime(seconds) {\n if (this._mediaElement) {\n this._mediaElement.currentTime = seconds;\n } else {\n this._pendingSeekTime = seconds;\n }\n }\n\n get mediaInfo() {\n let mediaPrefix = (this._mediaElement instanceof HTMLAudioElement) ? 'audio/' : 'video/';\n let info = {\n mimeType: mediaPrefix + this._mediaDataSource.type\n };\n if (this._mediaElement) {\n info.duration = Math.floor(this._mediaElement.duration * 1000);\n if (this._mediaElement instanceof HTMLVideoElement) {\n info.width = this._mediaElement.videoWidth;\n info.height = this._mediaElement.videoHeight;\n }\n }\n return info;\n }\n\n get statisticsInfo() {\n let info = {\n playerType: this._type,\n url: this._mediaDataSource.url\n };\n\n if (!(this._mediaElement instanceof HTMLVideoElement)) {\n return info;\n }\n\n let hasQualityInfo = true;\n let decoded = 0;\n let dropped = 0;\n\n if (this._mediaElement.getVideoPlaybackQuality) {\n let quality = this._mediaElement.getVideoPlaybackQuality();\n decoded = quality.totalVideoFrames;\n dropped = quality.droppedVideoFrames;\n } else if (this._mediaElement.webkitDecodedFrameCount != undefined) {\n decoded = this._mediaElement.webkitDecodedFrameCount;\n dropped = this._mediaElement.webkitDroppedFrameCount;\n } else {\n hasQualityInfo = false;\n }\n\n if (hasQualityInfo) {\n info.decodedFrames = decoded;\n info.droppedFrames = dropped;\n }\n \n return info;\n }\n\n _onvLoadedMetadata(e) {\n if (this._pendingSeekTime != null) {\n this._mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n }\n this._emitter.emit(PlayerEvents.MEDIA_INFO, this.mediaInfo);\n }\n\n _reportStatisticsInfo() {\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, this.statisticsInfo);\n }\n\n}\n\nexport default NativePlayer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {LoaderErrors} from '../io/loader.js';\nimport DemuxErrors from '../demux/demux-errors.js';\n\nexport const ErrorTypes = {\n NETWORK_ERROR: 'NetworkError',\n MEDIA_ERROR: 'MediaError',\n OTHER_ERROR: 'OtherError'\n};\n\nexport const ErrorDetails = {\n NETWORK_EXCEPTION: LoaderErrors.EXCEPTION,\n NETWORK_STATUS_CODE_INVALID: LoaderErrors.HTTP_STATUS_CODE_INVALID,\n NETWORK_TIMEOUT: LoaderErrors.CONNECTING_TIMEOUT,\n NETWORK_UNRECOVERABLE_EARLY_EOF: LoaderErrors.UNRECOVERABLE_EARLY_EOF,\n\n MEDIA_MSE_ERROR: 'MediaMSEError',\n\n MEDIA_FORMAT_ERROR: DemuxErrors.FORMAT_ERROR,\n MEDIA_FORMAT_UNSUPPORTED: DemuxErrors.FORMAT_UNSUPPORTED,\n MEDIA_CODEC_UNSUPPORTED: DemuxErrors.CODEC_UNSUPPORTED\n};","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst PlayerEvents = {\n ERROR: 'error',\n LOADING_COMPLETE: 'loading_complete',\n RECOVERED_EARLY_EOF: 'recovered_early_eof',\n MEDIA_INFO: 'media_info',\n STATISTICS_INFO: 'statistics_info'\n};\n\nexport default PlayerEvents;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * This file is modified from dailymotion's hls.js library (hls.js/src/helper/aac.js)\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass AAC {\n\n static getSilentFrame(codec, channelCount) {\n if (codec === 'mp4a.40.2') {\n // handle LC-AAC\n if (channelCount === 1) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);\n } else if (channelCount === 2) {\n return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]);\n } else if (channelCount === 3) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]);\n } else if (channelCount === 4) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]);\n } else if (channelCount === 5) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]);\n } else if (channelCount === 6) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]);\n }\n } else {\n // handle HE-AAC (mp4a.40.5 / mp4a.40.29)\n if (channelCount === 1) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0:d=0.05\" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);\n } else if (channelCount === 2) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0|0:d=0.05\" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);\n } else if (channelCount === 3) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0|0|0:d=0.05\" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);\n }\n }\n return null;\n }\n\n}\n\nexport default AAC;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * This file is derived from dailymotion's hls.js library (hls.js/src/remux/mp4-generator.js)\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// MP4 boxes generator for ISO BMFF (ISO Base Media File Format, defined in ISO/IEC 14496-12)\nclass MP4 {\n\n static init() {\n MP4.types = {\n avc1: [], avcC: [], btrt: [], dinf: [],\n dref: [], esds: [], ftyp: [], hdlr: [],\n mdat: [], mdhd: [], mdia: [], mfhd: [],\n minf: [], moof: [], moov: [], mp4a: [],\n mvex: [], mvhd: [], sdtp: [], stbl: [],\n stco: [], stsc: [], stsd: [], stsz: [],\n stts: [], tfdt: [], tfhd: [], traf: [],\n trak: [], trun: [], trex: [], tkhd: [],\n vmhd: [], smhd: [], '.mp3': []\n };\n\n for (let name in MP4.types) {\n if (MP4.types.hasOwnProperty(name)) {\n MP4.types[name] = [\n name.charCodeAt(0),\n name.charCodeAt(1),\n name.charCodeAt(2),\n name.charCodeAt(3)\n ];\n }\n }\n\n let constants = MP4.constants = {};\n\n constants.FTYP = new Uint8Array([\n 0x69, 0x73, 0x6F, 0x6D, // major_brand: isom\n 0x0, 0x0, 0x0, 0x1, // minor_version: 0x01\n 0x69, 0x73, 0x6F, 0x6D, // isom\n 0x61, 0x76, 0x63, 0x31 // avc1\n ]);\n\n constants.STSD_PREFIX = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x01 // entry_count\n ]);\n\n constants.STTS = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00 // entry_count\n ]);\n\n constants.STSC = constants.STCO = constants.STTS;\n\n constants.STSZ = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // sample_size\n 0x00, 0x00, 0x00, 0x00 // sample_count\n ]);\n\n constants.HDLR_VIDEO = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // pre_defined\n 0x76, 0x69, 0x64, 0x65, // handler_type: 'vide'\n 0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x56, 0x69, 0x64, 0x65,\n 0x6F, 0x48, 0x61, 0x6E,\n 0x64, 0x6C, 0x65, 0x72, 0x00 // name: VideoHandler\n ]);\n\n constants.HDLR_AUDIO = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // pre_defined\n 0x73, 0x6F, 0x75, 0x6E, // handler_type: 'soun'\n 0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x53, 0x6F, 0x75, 0x6E,\n 0x64, 0x48, 0x61, 0x6E,\n 0x64, 0x6C, 0x65, 0x72, 0x00 // name: SoundHandler\n ]);\n\n constants.DREF = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x01, // entry_count\n 0x00, 0x00, 0x00, 0x0C, // entry_size\n 0x75, 0x72, 0x6C, 0x20, // type 'url '\n 0x00, 0x00, 0x00, 0x01 // version(0) + flags\n ]);\n\n // Sound media header\n constants.SMHD = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00 // balance(2) + reserved(2)\n ]);\n\n // video media header\n constants.VMHD = new Uint8Array([\n 0x00, 0x00, 0x00, 0x01, // version(0) + flags\n 0x00, 0x00, // graphicsmode: 2 bytes\n 0x00, 0x00, 0x00, 0x00, // opcolor: 3 * 2 bytes\n 0x00, 0x00\n ]);\n }\n\n // Generate a box\n static box(type) {\n let size = 8;\n let result = null;\n let datas = Array.prototype.slice.call(arguments, 1);\n let arrayCount = datas.length;\n\n for (let i = 0; i < arrayCount; i++) {\n size += datas[i].byteLength;\n }\n\n result = new Uint8Array(size);\n result[0] = (size >>> 24) & 0xFF; // size\n result[1] = (size >>> 16) & 0xFF;\n result[2] = (size >>> 8) & 0xFF;\n result[3] = (size) & 0xFF;\n\n result.set(type, 4); // type\n\n let offset = 8;\n for (let i = 0; i < arrayCount; i++) { // data body\n result.set(datas[i], offset);\n offset += datas[i].byteLength;\n }\n\n return result;\n }\n\n // emit ftyp & moov\n static generateInitSegment(meta) {\n let ftyp = MP4.box(MP4.types.ftyp, MP4.constants.FTYP);\n let moov = MP4.moov(meta);\n\n let result = new Uint8Array(ftyp.byteLength + moov.byteLength);\n result.set(ftyp, 0);\n result.set(moov, ftyp.byteLength);\n return result;\n }\n\n // Movie metadata box\n static moov(meta) {\n let mvhd = MP4.mvhd(meta.timescale, meta.duration);\n let trak = MP4.trak(meta);\n let mvex = MP4.mvex(meta);\n return MP4.box(MP4.types.moov, mvhd, trak, mvex);\n }\n\n // Movie header box\n static mvhd(timescale, duration) {\n return MP4.box(MP4.types.mvhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // creation_time\n 0x00, 0x00, 0x00, 0x00, // modification_time\n (timescale >>> 24) & 0xFF, // timescale: 4 bytes\n (timescale >>> 16) & 0xFF,\n (timescale >>> 8) & 0xFF,\n (timescale) & 0xFF,\n (duration >>> 24) & 0xFF, // duration: 4 bytes\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n 0x00, 0x01, 0x00, 0x00, // Preferred rate: 1.0\n 0x01, 0x00, 0x00, 0x00, // PreferredVolume(1.0, 2bytes) + reserved(2bytes)\n 0x00, 0x00, 0x00, 0x00, // reserved: 4 + 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x01, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x40, 0x00, 0x00, 0x00, // ----end composition matrix----\n 0x00, 0x00, 0x00, 0x00, // ----begin pre_defined 6 * 4 bytes----\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, // ----end pre_defined 6 * 4 bytes----\n 0xFF, 0xFF, 0xFF, 0xFF // next_track_ID\n ]));\n }\n\n // Track box\n static trak(meta) {\n return MP4.box(MP4.types.trak, MP4.tkhd(meta), MP4.mdia(meta));\n }\n\n // Track header box\n static tkhd(meta) {\n let trackId = meta.id, duration = meta.duration;\n let width = meta.presentWidth, height = meta.presentHeight;\n\n return MP4.box(MP4.types.tkhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x07, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // creation_time\n 0x00, 0x00, 0x00, 0x00, // modification_time\n (trackId >>> 24) & 0xFF, // track_ID: 4 bytes\n (trackId >>> 16) & 0xFF,\n (trackId >>> 8) & 0xFF,\n (trackId) & 0xFF,\n 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes\n (duration >>> 24) & 0xFF, // duration: 4 bytes\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, // layer(2bytes) + alternate_group(2bytes)\n 0x00, 0x00, 0x00, 0x00, // volume(2bytes) + reserved(2bytes)\n 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x01, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x40, 0x00, 0x00, 0x00, // ----end composition matrix----\n (width >>> 8) & 0xFF, // width and height\n (width) & 0xFF,\n 0x00, 0x00,\n (height >>> 8) & 0xFF,\n (height) & 0xFF,\n 0x00, 0x00\n ]));\n }\n\n // Media Box\n static mdia(meta) {\n return MP4.box(MP4.types.mdia, MP4.mdhd(meta), MP4.hdlr(meta), MP4.minf(meta));\n }\n\n // Media header box\n static mdhd(meta) {\n let timescale = meta.timescale;\n let duration = meta.duration;\n return MP4.box(MP4.types.mdhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // creation_time\n 0x00, 0x00, 0x00, 0x00, // modification_time\n (timescale >>> 24) & 0xFF, // timescale: 4 bytes\n (timescale >>> 16) & 0xFF,\n (timescale >>> 8) & 0xFF,\n (timescale) & 0xFF,\n (duration >>> 24) & 0xFF, // duration: 4 bytes\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n 0x55, 0xC4, // language: und (undetermined)\n 0x00, 0x00 // pre_defined = 0\n ]));\n }\n\n // Media handler reference box\n static hdlr(meta) {\n let data = null;\n if (meta.type === 'audio') {\n data = MP4.constants.HDLR_AUDIO;\n } else {\n data = MP4.constants.HDLR_VIDEO;\n }\n return MP4.box(MP4.types.hdlr, data);\n }\n\n // Media infomation box\n static minf(meta) {\n let xmhd = null;\n if (meta.type === 'audio') {\n xmhd = MP4.box(MP4.types.smhd, MP4.constants.SMHD);\n } else {\n xmhd = MP4.box(MP4.types.vmhd, MP4.constants.VMHD);\n }\n return MP4.box(MP4.types.minf, xmhd, MP4.dinf(), MP4.stbl(meta));\n }\n\n // Data infomation box\n static dinf() {\n let result = MP4.box(MP4.types.dinf,\n MP4.box(MP4.types.dref, MP4.constants.DREF)\n );\n return result;\n }\n\n // Sample table box\n static stbl(meta) {\n let result = MP4.box(MP4.types.stbl, // type: stbl\n MP4.stsd(meta), // Sample Description Table\n MP4.box(MP4.types.stts, MP4.constants.STTS), // Time-To-Sample\n MP4.box(MP4.types.stsc, MP4.constants.STSC), // Sample-To-Chunk\n MP4.box(MP4.types.stsz, MP4.constants.STSZ), // Sample size\n MP4.box(MP4.types.stco, MP4.constants.STCO) // Chunk offset\n ); \n return result; \n }\n\n // Sample description box\n static stsd(meta) {\n if (meta.type === 'audio') {\n if (meta.codec === 'mp3') {\n return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp3(meta));\n }\n // else: aac -> mp4a\n return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp4a(meta));\n } else {\n return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.avc1(meta));\n }\n }\n\n static mp3(meta) {\n let channelCount = meta.channelCount;\n let sampleRate = meta.audioSampleRate;\n\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)\n 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, channelCount, // channelCount(2)\n 0x00, 0x10, // sampleSize(2)\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n (sampleRate >>> 8) & 0xFF, // Audio sample rate\n (sampleRate) & 0xFF,\n 0x00, 0x00\n ]);\n\n return MP4.box(MP4.types['.mp3'], data);\n }\n\n static mp4a(meta) {\n let channelCount = meta.channelCount;\n let sampleRate = meta.audioSampleRate;\n\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)\n 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, channelCount, // channelCount(2)\n 0x00, 0x10, // sampleSize(2)\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n (sampleRate >>> 8) & 0xFF, // Audio sample rate\n (sampleRate) & 0xFF,\n 0x00, 0x00\n ]);\n\n return MP4.box(MP4.types.mp4a, data, MP4.esds(meta));\n }\n\n static esds(meta) {\n let config = meta.config || [];\n let configSize = config.length;\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version 0 + flags\n\n 0x03, // descriptor_type\n 0x17 + configSize, // length3\n 0x00, 0x01, // es_id\n 0x00, // stream_priority\n\n 0x04, // descriptor_type\n 0x0F + configSize, // length\n 0x40, // codec: mpeg4_audio\n 0x15, // stream_type: Audio\n 0x00, 0x00, 0x00, // buffer_size\n 0x00, 0x00, 0x00, 0x00, // maxBitrate\n 0x00, 0x00, 0x00, 0x00, // avgBitrate\n\n 0x05 // descriptor_type\n ].concat([\n configSize\n ]).concat(\n config\n ).concat([\n 0x06, 0x01, 0x02 // GASpecificConfig\n ]));\n return MP4.box(MP4.types.esds, data);\n }\n\n static avc1(meta) {\n let avcc = meta.avcc;\n let width = meta.codecWidth, height = meta.codecHeight;\n\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)\n 0x00, 0x00, 0x00, 0x00, // pre_defined(2) + reserved(2)\n 0x00, 0x00, 0x00, 0x00, // pre_defined: 3 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n (width >>> 8) & 0xFF, // width: 2 bytes\n (width) & 0xFF,\n (height >>> 8) & 0xFF, // height: 2 bytes\n (height) & 0xFF,\n 0x00, 0x48, 0x00, 0x00, // horizresolution: 4 bytes\n 0x00, 0x48, 0x00, 0x00, // vertresolution: 4 bytes\n 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes\n 0x00, 0x01, // frame_count\n 0x0A, // strlen\n 0x78, 0x71, 0x71, 0x2F, // compressorname: 32 bytes\n 0x66, 0x6C, 0x76, 0x2E,\n 0x6A, 0x73, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00,\n 0x00, 0x18, // depth\n 0xFF, 0xFF // pre_defined = -1\n ]);\n return MP4.box(MP4.types.avc1, data, MP4.box(MP4.types.avcC, avcc));\n }\n\n // Movie Extends box\n static mvex(meta) {\n return MP4.box(MP4.types.mvex, MP4.trex(meta));\n }\n\n // Track Extends box\n static trex(meta) {\n let trackId = meta.id;\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n (trackId >>> 24) & 0xFF, // track_ID\n (trackId >>> 16) & 0xFF,\n (trackId >>> 8) & 0xFF,\n (trackId) & 0xFF,\n 0x00, 0x00, 0x00, 0x01, // default_sample_description_index\n 0x00, 0x00, 0x00, 0x00, // default_sample_duration\n 0x00, 0x00, 0x00, 0x00, // default_sample_size\n 0x00, 0x01, 0x00, 0x01 // default_sample_flags\n ]);\n return MP4.box(MP4.types.trex, data);\n }\n\n // Movie fragment box\n static moof(track, baseMediaDecodeTime) {\n return MP4.box(MP4.types.moof, MP4.mfhd(track.sequenceNumber), MP4.traf(track, baseMediaDecodeTime));\n }\n\n static mfhd(sequenceNumber) {\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00,\n (sequenceNumber >>> 24) & 0xFF, // sequence_number: int32\n (sequenceNumber >>> 16) & 0xFF,\n (sequenceNumber >>> 8) & 0xFF,\n (sequenceNumber) & 0xFF\n ]);\n return MP4.box(MP4.types.mfhd, data);\n }\n\n // Track fragment box\n static traf(track, baseMediaDecodeTime) {\n let trackId = track.id;\n\n // Track fragment header box\n let tfhd = MP4.box(MP4.types.tfhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) & flags\n (trackId >>> 24) & 0xFF, // track_ID\n (trackId >>> 16) & 0xFF,\n (trackId >>> 8) & 0xFF,\n (trackId) & 0xFF\n ]));\n // Track Fragment Decode Time\n let tfdt = MP4.box(MP4.types.tfdt, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) & flags\n (baseMediaDecodeTime >>> 24) & 0xFF, // baseMediaDecodeTime: int32\n (baseMediaDecodeTime >>> 16) & 0xFF,\n (baseMediaDecodeTime >>> 8) & 0xFF,\n (baseMediaDecodeTime) & 0xFF\n ]));\n let sdtp = MP4.sdtp(track);\n let trun = MP4.trun(track, sdtp.byteLength + 16 + 16 + 8 + 16 + 8 + 8);\n\n return MP4.box(MP4.types.traf, tfhd, tfdt, trun, sdtp);\n }\n\n // Sample Dependency Type box\n static sdtp(track) {\n let samples = track.samples || [];\n let sampleCount = samples.length;\n let data = new Uint8Array(4 + sampleCount);\n // 0~4 bytes: version(0) & flags\n for (let i = 0; i < sampleCount; i++) {\n let flags = samples[i].flags;\n data[i + 4] = (flags.isLeading << 6) // is_leading: 2 (bit)\n | (flags.dependsOn << 4) // sample_depends_on\n | (flags.isDependedOn << 2) // sample_is_depended_on\n | (flags.hasRedundancy); // sample_has_redundancy\n }\n return MP4.box(MP4.types.sdtp, data);\n }\n\n // Track fragment run box\n static trun(track, offset) {\n let samples = track.samples || [];\n let sampleCount = samples.length;\n let dataSize = 12 + 16 * sampleCount;\n let data = new Uint8Array(dataSize);\n offset += 8 + dataSize;\n\n data.set([\n 0x00, 0x00, 0x0F, 0x01, // version(0) & flags\n (sampleCount >>> 24) & 0xFF, // sample_count\n (sampleCount >>> 16) & 0xFF,\n (sampleCount >>> 8) & 0xFF,\n (sampleCount) & 0xFF,\n (offset >>> 24) & 0xFF, // data_offset\n (offset >>> 16) & 0xFF,\n (offset >>> 8) & 0xFF,\n (offset) & 0xFF\n ], 0);\n\n for (let i = 0; i < sampleCount; i++) {\n let duration = samples[i].duration;\n let size = samples[i].size;\n let flags = samples[i].flags;\n let cts = samples[i].cts;\n data.set([\n (duration >>> 24) & 0xFF, // sample_duration\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n (size >>> 24) & 0xFF, // sample_size\n (size >>> 16) & 0xFF,\n (size >>> 8) & 0xFF,\n (size) & 0xFF,\n (flags.isLeading << 2) | flags.dependsOn, // sample_flags\n (flags.isDependedOn << 6) | (flags.hasRedundancy << 4) | flags.isNonSync,\n 0x00, 0x00, // sample_degradation_priority\n (cts >>> 24) & 0xFF, // sample_composition_time_offset\n (cts >>> 16) & 0xFF,\n (cts >>> 8) & 0xFF,\n (cts) & 0xFF\n ], 12 + 16 * i);\n }\n return MP4.box(MP4.types.trun, data);\n }\n\n static mdat(data) {\n return MP4.box(MP4.types.mdat, data);\n }\n\n}\n\nMP4.init();\n\nexport default MP4;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport MP4 from './mp4-generator.js';\nimport AAC from './aac-silent.js';\nimport Browser from '../utils/browser.js';\nimport {SampleInfo, MediaSegmentInfo, MediaSegmentInfoList} from '../core/media-segment-info.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\n\n// Fragmented mp4 remuxer\nclass MP4Remuxer {\n\n constructor(config) {\n this.TAG = 'MP4Remuxer';\n\n this._config = config;\n this._isLive = (config.isLive === true) ? true : false;\n\n this._dtsBase = -1;\n this._dtsBaseInited = false;\n this._audioDtsBase = Infinity;\n this._videoDtsBase = Infinity;\n this._audioNextDts = undefined;\n this._videoNextDts = undefined;\n\n this._audioMeta = null;\n this._videoMeta = null;\n\n this._audioSegmentInfoList = new MediaSegmentInfoList('audio');\n this._videoSegmentInfoList = new MediaSegmentInfoList('video');\n\n this._onInitSegment = null;\n this._onMediaSegment = null;\n\n // Workaround for chrome < 50: Always force first sample as a Random Access Point in media segment\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412\n this._forceFirstIDR = (Browser.chrome &&\n (Browser.version.major < 50 ||\n (Browser.version.major === 50 && Browser.version.build < 2661))) ? true : false;\n\n // Workaround for IE11/Edge: Fill silent aac frame after keyframe-seeking\n // Make audio beginDts equals with video beginDts, in order to fix seek freeze\n this._fillSilentAfterSeek = (Browser.msedge || Browser.msie);\n\n // While only FireFox supports 'audio/mp4, codecs=\"mp3\"', use 'audio/mpeg' for chrome, safari, ...\n this._mp3UseMpegAudio = !Browser.firefox;\n\n this._fillAudioTimestampGap = this._config.fixAudioTimestampGap;\n }\n\n destroy() {\n this._dtsBase = -1;\n this._dtsBaseInited = false;\n this._audioMeta = null;\n this._videoMeta = null;\n this._audioSegmentInfoList.clear();\n this._audioSegmentInfoList = null;\n this._videoSegmentInfoList.clear();\n this._videoSegmentInfoList = null;\n this._onInitSegment = null;\n this._onMediaSegment = null;\n }\n\n bindDataSource(producer) {\n producer.onDataAvailable = this.remux.bind(this);\n producer.onTrackMetadata = this._onTrackMetadataReceived.bind(this);\n return this;\n }\n\n /* prototype: function onInitSegment(type: string, initSegment: ArrayBuffer): void\n InitSegment: {\n type: string,\n data: ArrayBuffer,\n codec: string,\n container: string\n }\n */\n get onInitSegment() {\n return this._onInitSegment;\n }\n\n set onInitSegment(callback) {\n this._onInitSegment = callback;\n }\n\n /* prototype: function onMediaSegment(type: string, mediaSegment: MediaSegment): void\n MediaSegment: {\n type: string,\n data: ArrayBuffer,\n sampleCount: int32\n info: MediaSegmentInfo\n }\n */\n get onMediaSegment() {\n return this._onMediaSegment;\n }\n\n set onMediaSegment(callback) {\n this._onMediaSegment = callback;\n }\n\n insertDiscontinuity() {\n this._audioNextDts = this._videoNextDts = undefined;\n }\n\n seek(originalDts) {\n this._videoSegmentInfoList.clear();\n this._audioSegmentInfoList.clear();\n }\n\n remux(audioTrack, videoTrack) {\n if (!this._onMediaSegment) {\n throw new IllegalStateException('MP4Remuxer: onMediaSegment callback must be specificed!');\n }\n if (!this._dtsBaseInited) {\n this._calculateDtsBase(audioTrack, videoTrack);\n }\n this._remuxVideo(videoTrack);\n this._remuxAudio(audioTrack);\n }\n\n _onTrackMetadataReceived(type, metadata) {\n let metabox = null;\n\n let container = 'mp4';\n let codec = metadata.codec;\n\n if (type === 'audio') {\n this._audioMeta = metadata;\n if (metadata.codec === 'mp3' && this._mp3UseMpegAudio) {\n // 'audio/mpeg' for MP3 audio track\n container = 'mpeg';\n codec = '';\n metabox = new Uint8Array();\n } else {\n // 'audio/mp4, codecs=\"codec\"'\n metabox = MP4.generateInitSegment(metadata);\n }\n } else if (type === 'video') {\n this._videoMeta = metadata;\n metabox = MP4.generateInitSegment(metadata);\n } else {\n return;\n }\n\n // dispatch metabox (Initialization Segment)\n if (!this._onInitSegment) {\n throw new IllegalStateException('MP4Remuxer: onInitSegment callback must be specified!');\n }\n this._onInitSegment(type, {\n type: type,\n data: metabox.buffer,\n codec: codec,\n container: `${type}/${container}`,\n mediaDuration: metadata.duration // in timescale 1000 (milliseconds)\n });\n }\n\n _calculateDtsBase(audioTrack, videoTrack) {\n if (this._dtsBaseInited) {\n return;\n }\n\n if (audioTrack.samples && audioTrack.samples.length) {\n this._audioDtsBase = audioTrack.samples[0].dts;\n }\n if (videoTrack.samples && videoTrack.samples.length) {\n this._videoDtsBase = videoTrack.samples[0].dts;\n }\n\n this._dtsBase = Math.min(this._audioDtsBase, this._videoDtsBase);\n this._dtsBaseInited = true;\n }\n\n _remuxAudio(audioTrack) {\n if (this._audioMeta == null) {\n return;\n }\n\n let track = audioTrack;\n let samples = track.samples;\n let dtsCorrection = undefined;\n let firstDts = -1, lastDts = -1, lastPts = -1;\n let refSampleDuration = this._audioMeta.refSampleDuration;\n\n let mpegRawTrack = this._audioMeta.codec === 'mp3' && this._mp3UseMpegAudio;\n let firstSegmentAfterSeek = this._dtsBaseInited && this._audioNextDts === undefined;\n\n let insertPrefixSilentFrame = false;\n\n if (!samples || samples.length === 0) {\n return;\n }\n\n let offset = 0;\n let mdatbox = null;\n let mdatBytes = 0;\n\n // calculate initial mdat size\n if (mpegRawTrack) {\n // for raw mpeg buffer\n offset = 0;\n mdatBytes = track.length;\n } else {\n // for fmp4 mdat box\n offset = 8; // size + type\n mdatBytes = 8 + track.length;\n }\n\n let firstSampleOriginalDts = samples[0].dts - this._dtsBase;\n\n // calculate dtsCorrection\n if (this._audioNextDts) {\n dtsCorrection = firstSampleOriginalDts - this._audioNextDts;\n } else { // this._audioNextDts == undefined\n if (this._audioSegmentInfoList.isEmpty()) {\n dtsCorrection = 0;\n if (this._fillSilentAfterSeek && !this._videoSegmentInfoList.isEmpty()) {\n if (this._audioMeta.originalCodec !== 'mp3') {\n insertPrefixSilentFrame = true;\n }\n }\n } else {\n let lastSample = this._audioSegmentInfoList.getLastSampleBefore(firstSampleOriginalDts);\n if (lastSample != null) {\n let distance = (firstSampleOriginalDts - (lastSample.originalDts + lastSample.duration));\n if (distance <= 3) {\n distance = 0;\n }\n let expectedDts = lastSample.dts + lastSample.duration + distance;\n dtsCorrection = firstSampleOriginalDts - expectedDts;\n } else { // lastSample == null, cannot found\n dtsCorrection = 0;\n }\n }\n }\n\n if (insertPrefixSilentFrame) {\n // align audio segment beginDts to match with current video segment's beginDts\n let firstSampleDts = firstSampleOriginalDts - dtsCorrection;\n let videoSegment = this._videoSegmentInfoList.getLastSegmentBefore(firstSampleOriginalDts);\n if (videoSegment != null && videoSegment.beginDts < firstSampleDts) {\n let silentUnit = AAC.getSilentFrame(this._audioMeta.originalCodec, this._audioMeta.channelCount);\n if (silentUnit) {\n let dts = videoSegment.beginDts;\n let silentFrameDuration = firstSampleDts - videoSegment.beginDts;\n Log.v(this.TAG, `InsertPrefixSilentAudio: dts: ${dts}, duration: ${silentFrameDuration}`);\n samples.unshift({unit: silentUnit, dts: dts, pts: dts});\n mdatBytes += silentUnit.byteLength;\n } // silentUnit == null: Cannot generate, skip\n } else {\n insertPrefixSilentFrame = false;\n }\n }\n\n let mp4Samples = [];\n\n // Correct dts for each sample, and calculate sample duration. Then output to mp4Samples\n for (let i = 0; i < samples.length; i++) {\n let sample = samples[i];\n let unit = sample.unit;\n let originalDts = sample.dts - this._dtsBase;\n let dts = originalDts - dtsCorrection;\n\n if (firstDts === -1) {\n firstDts = dts;\n }\n\n let sampleDuration = 0;\n\n if (i !== samples.length - 1) {\n let nextDts = samples[i + 1].dts - this._dtsBase - dtsCorrection;\n sampleDuration = nextDts - dts;\n } else { // the last sample\n if (mp4Samples.length >= 1) { // use second last sample duration\n sampleDuration = mp4Samples[mp4Samples.length - 1].duration;\n } else { // the only one sample, use reference sample duration\n sampleDuration = Math.floor(refSampleDuration);\n }\n }\n\n let needFillSilentFrames = false;\n let silentFrames = null;\n\n // Silent frame generation, if large timestamp gap detected && config.fixAudioTimestampGap\n if (sampleDuration > refSampleDuration * 1.5 && this._audioMeta.codec !== 'mp3' && this._fillAudioTimestampGap && !Browser.safari) {\n // We need to insert silent frames to fill timestamp gap\n needFillSilentFrames = true;\n let delta = Math.abs(sampleDuration - refSampleDuration);\n let frameCount = Math.ceil(delta / refSampleDuration);\n let currentDts = dts + refSampleDuration; // Notice: in float\n\n Log.w(this.TAG, 'Large audio timestamp gap detected, may cause AV sync to drift. ' +\n 'Silent frames will be generated to avoid unsync.\\n' +\n `dts: ${dts + sampleDuration} ms, expected: ${dts + Math.round(refSampleDuration)} ms, ` +\n `delta: ${Math.round(delta)} ms, generate: ${frameCount} frames`);\n\n let silentUnit = AAC.getSilentFrame(this._audioMeta.originalCodec, this._audioMeta.channelCount);\n if (silentUnit == null) {\n Log.w(this.TAG, 'Unable to generate silent frame for ' +\n `${this._audioMeta.originalCodec} with ${this._audioMeta.channelCount} channels, repeat last frame`);\n // Repeat last frame\n silentUnit = unit;\n }\n silentFrames = [];\n\n for (let j = 0; j < frameCount; j++) {\n let intDts = Math.round(currentDts); // round to integer\n if (silentFrames.length > 0) {\n // Set previous frame sample duration\n let previousFrame = silentFrames[silentFrames.length - 1];\n previousFrame.duration = intDts - previousFrame.dts;\n }\n let frame = {\n dts: intDts,\n pts: intDts,\n cts: 0,\n unit: silentUnit,\n size: silentUnit.byteLength,\n duration: 0, // wait for next sample\n originalDts: originalDts,\n flags: {\n isLeading: 0,\n dependsOn: 1,\n isDependedOn: 0,\n hasRedundancy: 0\n }\n };\n silentFrames.push(frame);\n mdatBytes += unit.byteLength;\n currentDts += refSampleDuration;\n }\n\n // last frame: align end time to next frame dts\n let lastFrame = silentFrames[silentFrames.length - 1];\n lastFrame.duration = dts + sampleDuration - lastFrame.dts;\n\n // silentFrames.forEach((frame) => {\n // Log.w(this.TAG, `SilentAudio: dts: ${frame.dts}, duration: ${frame.duration}`);\n // });\n\n // Set correct sample duration for current frame\n sampleDuration = Math.round(refSampleDuration);\n }\n\n mp4Samples.push({\n dts: dts,\n pts: dts,\n cts: 0,\n unit: sample.unit,\n size: sample.unit.byteLength,\n duration: sampleDuration,\n originalDts: originalDts,\n flags: {\n isLeading: 0,\n dependsOn: 1,\n isDependedOn: 0,\n hasRedundancy: 0\n }\n });\n\n if (needFillSilentFrames) {\n // Silent frames should be inserted after wrong-duration frame\n mp4Samples.push.apply(mp4Samples, silentFrames);\n }\n }\n\n // allocate mdatbox\n if (mpegRawTrack) {\n // allocate for raw mpeg buffer\n mdatbox = new Uint8Array(mdatBytes);\n } else {\n // allocate for fmp4 mdat box\n mdatbox = new Uint8Array(mdatBytes);\n // size field\n mdatbox[0] = (mdatBytes >>> 24) & 0xFF;\n mdatbox[1] = (mdatBytes >>> 16) & 0xFF;\n mdatbox[2] = (mdatBytes >>> 8) & 0xFF;\n mdatbox[3] = (mdatBytes) & 0xFF;\n // type field (fourCC)\n mdatbox.set(MP4.types.mdat, 4);\n }\n\n // Write samples into mdatbox\n for (let i = 0; i < mp4Samples.length; i++) {\n let unit = mp4Samples[i].unit;\n mdatbox.set(unit, offset);\n offset += unit.byteLength;\n }\n\n let latest = mp4Samples[mp4Samples.length - 1];\n lastDts = latest.dts + latest.duration;\n this._audioNextDts = lastDts;\n\n // fill media segment info & add to info list\n let info = new MediaSegmentInfo();\n info.beginDts = firstDts;\n info.endDts = lastDts;\n info.beginPts = firstDts;\n info.endPts = lastDts;\n info.originalBeginDts = mp4Samples[0].originalDts;\n info.originalEndDts = latest.originalDts + latest.duration;\n info.firstSample = new SampleInfo(mp4Samples[0].dts,\n mp4Samples[0].pts,\n mp4Samples[0].duration,\n mp4Samples[0].originalDts,\n false);\n info.lastSample = new SampleInfo(latest.dts,\n latest.pts,\n latest.duration,\n latest.originalDts,\n false);\n if (!this._isLive) {\n this._audioSegmentInfoList.append(info);\n }\n\n track.samples = mp4Samples;\n track.sequenceNumber++;\n\n let moofbox = null;\n\n if (mpegRawTrack) {\n // Generate empty buffer, because useless for raw mpeg\n moofbox = new Uint8Array();\n } else {\n // Generate moof for fmp4 segment\n moofbox = MP4.moof(track, firstDts);\n }\n\n track.samples = [];\n track.length = 0;\n\n let segment = {\n type: 'audio',\n data: this._mergeBoxes(moofbox, mdatbox).buffer,\n sampleCount: mp4Samples.length,\n info: info\n };\n\n if (mpegRawTrack && firstSegmentAfterSeek) {\n // For MPEG audio stream in MSE, if seeking occurred, before appending new buffer\n // We need explicitly set timestampOffset to the desired point in timeline for mpeg SourceBuffer.\n segment.timestampOffset = firstDts;\n }\n\n this._onMediaSegment('audio', segment);\n }\n\n _remuxVideo(videoTrack) {\n if (this._videoMeta == null) {\n return;\n }\n\n let track = videoTrack;\n let samples = track.samples;\n let dtsCorrection = undefined;\n let firstDts = -1, lastDts = -1;\n let firstPts = -1, lastPts = -1;\n\n if (!samples || samples.length === 0) {\n return;\n }\n\n let offset = 8;\n let mdatBytes = 8 + videoTrack.length;\n let mdatbox = new Uint8Array(mdatBytes);\n mdatbox[0] = (mdatBytes >>> 24) & 0xFF;\n mdatbox[1] = (mdatBytes >>> 16) & 0xFF;\n mdatbox[2] = (mdatBytes >>> 8) & 0xFF;\n mdatbox[3] = (mdatBytes) & 0xFF;\n mdatbox.set(MP4.types.mdat, 4);\n\n let firstSampleOriginalDts = samples[0].dts - this._dtsBase;\n\n // calculate dtsCorrection\n if (this._videoNextDts) {\n dtsCorrection = firstSampleOriginalDts - this._videoNextDts;\n } else { // this._videoNextDts == undefined\n if (this._videoSegmentInfoList.isEmpty()) {\n dtsCorrection = 0;\n } else {\n let lastSample = this._videoSegmentInfoList.getLastSampleBefore(firstSampleOriginalDts);\n if (lastSample != null) {\n let distance = (firstSampleOriginalDts - (lastSample.originalDts + lastSample.duration));\n if (distance <= 3) {\n distance = 0;\n }\n let expectedDts = lastSample.dts + lastSample.duration + distance;\n dtsCorrection = firstSampleOriginalDts - expectedDts;\n } else { // lastSample == null, cannot found\n dtsCorrection = 0;\n }\n }\n }\n\n let info = new MediaSegmentInfo();\n let mp4Samples = [];\n\n // Correct dts for each sample, and calculate sample duration. Then output to mp4Samples\n for (let i = 0; i < samples.length; i++) {\n let sample = samples[i];\n let originalDts = sample.dts - this._dtsBase;\n let isKeyframe = sample.isKeyframe;\n let dts = originalDts - dtsCorrection;\n let cts = sample.cts;\n let pts = dts + cts;\n\n if (firstDts === -1) {\n firstDts = dts;\n firstPts = pts;\n }\n\n let sampleDuration = 0;\n\n if (i !== samples.length - 1) {\n let nextDts = samples[i + 1].dts - this._dtsBase - dtsCorrection;\n sampleDuration = nextDts - dts;\n } else { // the last sample\n if (mp4Samples.length >= 1) { // use second last sample duration\n sampleDuration = mp4Samples[mp4Samples.length - 1].duration;\n } else { // the only one sample, use reference sample duration\n sampleDuration = Math.floor(this._videoMeta.refSampleDuration);\n }\n }\n\n if (isKeyframe) {\n let syncPoint = new SampleInfo(dts, pts, sampleDuration, sample.dts, true);\n syncPoint.fileposition = sample.fileposition;\n info.appendSyncPoint(syncPoint);\n }\n\n mp4Samples.push({\n dts: dts,\n pts: pts,\n cts: cts,\n units: sample.units,\n size: sample.length,\n isKeyframe: isKeyframe,\n duration: sampleDuration,\n originalDts: originalDts,\n flags: {\n isLeading: 0,\n dependsOn: isKeyframe ? 2 : 1,\n isDependedOn: isKeyframe ? 1 : 0,\n hasRedundancy: 0,\n isNonSync: isKeyframe ? 0 : 1\n }\n });\n }\n\n // Write samples into mdatbox\n for (let i = 0; i < mp4Samples.length; i++) {\n let units = mp4Samples[i].units;\n while (units.length) {\n let unit = units.shift();\n let data = unit.data;\n mdatbox.set(data, offset);\n offset += data.byteLength;\n }\n }\n\n let latest = mp4Samples[mp4Samples.length - 1];\n lastDts = latest.dts + latest.duration;\n lastPts = latest.pts + latest.duration;\n this._videoNextDts = lastDts;\n\n // fill media segment info & add to info list\n info.beginDts = firstDts;\n info.endDts = lastDts;\n info.beginPts = firstPts;\n info.endPts = lastPts;\n info.originalBeginDts = mp4Samples[0].originalDts;\n info.originalEndDts = latest.originalDts + latest.duration;\n info.firstSample = new SampleInfo(mp4Samples[0].dts,\n mp4Samples[0].pts,\n mp4Samples[0].duration,\n mp4Samples[0].originalDts,\n mp4Samples[0].isKeyframe);\n info.lastSample = new SampleInfo(latest.dts,\n latest.pts,\n latest.duration,\n latest.originalDts,\n latest.isKeyframe);\n if (!this._isLive) {\n this._videoSegmentInfoList.append(info);\n }\n\n track.samples = mp4Samples;\n track.sequenceNumber++;\n\n // workaround for chrome < 50: force first sample as a random access point\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412\n if (this._forceFirstIDR) {\n let flags = mp4Samples[0].flags;\n flags.dependsOn = 2;\n flags.isNonSync = 0;\n }\n\n let moofbox = MP4.moof(track, firstDts);\n track.samples = [];\n track.length = 0;\n\n this._onMediaSegment('video', {\n type: 'video',\n data: this._mergeBoxes(moofbox, mdatbox).buffer,\n sampleCount: mp4Samples.length,\n info: info\n });\n }\n\n _mergeBoxes(moof, mdat) {\n let result = new Uint8Array(moof.byteLength + mdat.byteLength);\n result.set(moof, 0);\n result.set(mdat, moof.byteLength);\n return result;\n }\n\n}\n\nexport default MP4Remuxer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nlet Browser = {};\n\nfunction detect() {\n // modified from jquery-browser-plugin\n\n let ua = self.navigator.userAgent.toLowerCase();\n\n let match = /(edge)\\/([\\w.]+)/.exec(ua) ||\n /(opr)[\\/]([\\w.]+)/.exec(ua) ||\n /(chrome)[ \\/]([\\w.]+)/.exec(ua) ||\n /(iemobile)[\\/]([\\w.]+)/.exec(ua) ||\n /(version)(applewebkit)[ \\/]([\\w.]+).*(safari)[ \\/]([\\w.]+)/.exec(ua) ||\n /(webkit)[ \\/]([\\w.]+).*(version)[ \\/]([\\w.]+).*(safari)[ \\/]([\\w.]+)/.exec(ua) ||\n /(webkit)[ \\/]([\\w.]+)/.exec(ua) ||\n /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec(ua) ||\n /(msie) ([\\w.]+)/.exec(ua) ||\n ua.indexOf('trident') >= 0 && /(rv)(?::| )([\\w.]+)/.exec(ua) ||\n ua.indexOf('compatible') < 0 && /(firefox)[ \\/]([\\w.]+)/.exec(ua) ||\n [];\n\n let platform_match = /(ipad)/.exec(ua) ||\n /(ipod)/.exec(ua) ||\n /(windows phone)/.exec(ua) ||\n /(iphone)/.exec(ua) ||\n /(kindle)/.exec(ua) ||\n /(android)/.exec(ua) ||\n /(windows)/.exec(ua) ||\n /(mac)/.exec(ua) ||\n /(linux)/.exec(ua) ||\n /(cros)/.exec(ua) ||\n [];\n\n let matched = {\n browser: match[5] || match[3] || match[1] || '',\n version: match[2] || match[4] || '0',\n majorVersion: match[4] || match[2] || '0',\n platform: platform_match[0] || ''\n };\n\n let browser = {};\n if (matched.browser) {\n browser[matched.browser] = true;\n\n let versionArray = matched.majorVersion.split('.');\n browser.version = {\n major: parseInt(matched.majorVersion, 10),\n string: matched.version\n };\n if (versionArray.length > 1) {\n browser.version.minor = parseInt(versionArray[1], 10);\n }\n if (versionArray.length > 2) {\n browser.version.build = parseInt(versionArray[2], 10);\n }\n }\n\n if (matched.platform) {\n browser[matched.platform] = true;\n }\n\n if (browser.chrome || browser.opr || browser.safari) {\n browser.webkit = true;\n }\n\n // MSIE. IE11 has 'rv' identifer\n if (browser.rv || browser.iemobile) {\n if (browser.rv) {\n delete browser.rv;\n }\n let msie = 'msie';\n matched.browser = msie;\n browser[msie] = true;\n }\n\n // Microsoft Edge\n if (browser.edge) {\n delete browser.edge;\n let msedge = 'msedge';\n matched.browser = msedge;\n browser[msedge] = true;\n }\n\n // Opera 15+\n if (browser.opr) {\n let opera = 'opera';\n matched.browser = opera;\n browser[opera] = true;\n }\n\n // Stock android browsers are marked as Safari\n if (browser.safari && browser.android) {\n let android = 'android';\n matched.browser = android;\n browser[android] = true;\n }\n\n browser.name = matched.browser;\n browser.platform = matched.platform;\n\n for (let key in Browser) {\n if (Browser.hasOwnProperty(key)) {\n delete Browser[key];\n }\n }\n Object.assign(Browser, browser);\n}\n\ndetect();\n\nexport default Browser;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class RuntimeException {\n\n constructor(message) {\n this._message = message;\n }\n\n get name() {\n return 'RuntimeException';\n }\n\n get message() {\n return this._message;\n }\n\n toString() {\n return this.name + ': ' + this.message;\n }\n\n}\n\nexport class IllegalStateException extends RuntimeException {\n\n constructor(message) {\n super(message);\n }\n\n get name() {\n return 'IllegalStateException';\n }\n\n}\n\nexport class InvalidArgumentException extends RuntimeException {\n\n constructor(message) {\n super(message);\n }\n\n get name() {\n return 'InvalidArgumentException';\n }\n\n}\n\nexport class NotImplementedException extends RuntimeException {\n\n constructor(message) {\n super(message);\n }\n\n get name() {\n return 'NotImplementedException';\n }\n\n}\n","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\n\nclass Log {\n\n static e(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'error', str);\n }\n\n if (!Log.ENABLE_ERROR) {\n return;\n }\n\n if (console.error) {\n console.error(str);\n } else if (console.warn) {\n console.warn(str);\n } else {\n console.log(str);\n }\n }\n\n static i(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'info', str);\n }\n\n if (!Log.ENABLE_INFO) {\n return;\n }\n\n if (console.info) {\n console.info(str);\n } else {\n console.log(str);\n }\n }\n\n static w(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'warn', str);\n }\n\n if (!Log.ENABLE_WARN) {\n return;\n }\n\n if (console.warn) {\n console.warn(str);\n } else {\n console.log(str);\n }\n }\n\n static d(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'debug', str);\n }\n\n if (!Log.ENABLE_DEBUG) {\n return;\n }\n\n if (console.debug) {\n console.debug(str);\n } else {\n console.log(str);\n }\n }\n\n static v(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'verbose', str);\n }\n\n if (!Log.ENABLE_VERBOSE) {\n return;\n }\n\n console.log(str);\n }\n\n}\n\nLog.GLOBAL_TAG = 'flv.js';\nLog.FORCE_GLOBAL_TAG = false;\nLog.ENABLE_ERROR = true;\nLog.ENABLE_INFO = true;\nLog.ENABLE_WARN = true;\nLog.ENABLE_DEBUG = true;\nLog.ENABLE_VERBOSE = true;\n\nLog.ENABLE_CALLBACK = false;\n\nLog.emitter = new EventEmitter();\n\nexport default Log;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from './logger.js';\n\nclass LoggingControl {\n\n static get forceGlobalTag() {\n return Log.FORCE_GLOBAL_TAG;\n }\n\n static set forceGlobalTag(enable) {\n Log.FORCE_GLOBAL_TAG = enable;\n LoggingControl._notifyChange();\n }\n\n static get globalTag() {\n return Log.GLOBAL_TAG;\n }\n\n static set globalTag(tag) {\n Log.GLOBAL_TAG = tag;\n LoggingControl._notifyChange();\n }\n\n static get enableAll() {\n return Log.ENABLE_VERBOSE\n && Log.ENABLE_DEBUG\n && Log.ENABLE_INFO\n && Log.ENABLE_WARN\n && Log.ENABLE_ERROR;\n }\n\n static set enableAll(enable) {\n Log.ENABLE_VERBOSE = enable;\n Log.ENABLE_DEBUG = enable;\n Log.ENABLE_INFO = enable;\n Log.ENABLE_WARN = enable;\n Log.ENABLE_ERROR = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableDebug() {\n return Log.ENABLE_DEBUG;\n }\n\n static set enableDebug(enable) {\n Log.ENABLE_DEBUG = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableVerbose() {\n return Log.ENABLE_VERBOSE;\n }\n\n static set enableVerbose(enable) {\n Log.ENABLE_VERBOSE = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableInfo() {\n return Log.ENABLE_INFO;\n }\n\n static set enableInfo(enable) {\n Log.ENABLE_INFO = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableWarn() {\n return Log.ENABLE_WARN;\n }\n\n static set enableWarn(enable) {\n Log.ENABLE_WARN = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableError() {\n return Log.ENABLE_ERROR;\n }\n\n static set enableError(enable) {\n Log.ENABLE_ERROR = enable;\n LoggingControl._notifyChange();\n }\n\n static getConfig() {\n return {\n globalTag: Log.GLOBAL_TAG,\n forceGlobalTag: Log.FORCE_GLOBAL_TAG,\n enableVerbose: Log.ENABLE_VERBOSE,\n enableDebug: Log.ENABLE_DEBUG,\n enableInfo: Log.ENABLE_INFO,\n enableWarn: Log.ENABLE_WARN,\n enableError: Log.ENABLE_ERROR,\n enableCallback: Log.ENABLE_CALLBACK\n };\n }\n\n static applyConfig(config) {\n Log.GLOBAL_TAG = config.globalTag;\n Log.FORCE_GLOBAL_TAG = config.forceGlobalTag;\n Log.ENABLE_VERBOSE = config.enableVerbose;\n Log.ENABLE_DEBUG = config.enableDebug;\n Log.ENABLE_INFO = config.enableInfo;\n Log.ENABLE_WARN = config.enableWarn;\n Log.ENABLE_ERROR = config.enableError;\n Log.ENABLE_CALLBACK = config.enableCallback;\n }\n\n static _notifyChange() {\n let emitter = LoggingControl.emitter;\n\n if (emitter.listenerCount('change') > 0) {\n let config = LoggingControl.getConfig();\n emitter.emit('change', config);\n }\n }\n\n static registerListener(listener) {\n LoggingControl.emitter.addListener('change', listener);\n }\n\n static removeListener(listener) {\n LoggingControl.emitter.removeListener('change', listener);\n }\n\n static addLogListener(listener) {\n Log.emitter.addListener('log', listener);\n if (Log.emitter.listenerCount('log') > 0) {\n Log.ENABLE_CALLBACK = true;\n LoggingControl._notifyChange();\n }\n }\n\n static removeLogListener(listener) {\n Log.emitter.removeListener('log', listener);\n if (Log.emitter.listenerCount('log') === 0) {\n Log.ENABLE_CALLBACK = false;\n LoggingControl._notifyChange();\n }\n }\n\n}\n\nLoggingControl.emitter = new EventEmitter();\n\nexport default LoggingControl;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass Polyfill {\n\n static install() {\n // ES6 Object.setPrototypeOf\n Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {\n obj.__proto__ = proto;\n return obj;\n };\n\n // ES6 Object.assign\n Object.assign = Object.assign || function (target) {\n if (target === undefined || target === null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n let output = Object(target);\n for (let i = 1; i < arguments.length; i++) {\n let source = arguments[i];\n if (source !== undefined && source !== null) {\n for (let key in source) {\n if (source.hasOwnProperty(key)) {\n output[key] = source[key];\n }\n }\n }\n }\n return output;\n };\n\n // ES6 Promise (missing support in IE11)\n if (typeof self.Promise !== 'function') {\n require('es6-promise').polyfill();\n }\n }\n\n}\n\nPolyfill.install();\n\nexport default Polyfill;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * This file is derived from C++ project libWinTF8 (https://github.com/m13253/libWinTF8)\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nfunction checkContinuation(uint8array, start, checkLength) {\n let array = uint8array;\n if (start + checkLength < array.length) {\n while (checkLength--) {\n if ((array[++start] & 0xC0) !== 0x80)\n return false;\n }\n return true;\n } else {\n return false;\n }\n}\n\nfunction decodeUTF8(uint8array) {\n let out = [];\n let input = uint8array;\n let i = 0;\n let length = uint8array.length;\n\n while (i < length) {\n if (input[i] < 0x80) {\n out.push(String.fromCharCode(input[i]));\n ++i;\n continue;\n } else if (input[i] < 0xC0) {\n // fallthrough\n } else if (input[i] < 0xE0) {\n if (checkContinuation(input, i, 1)) {\n let ucs4 = (input[i] & 0x1F) << 6 | (input[i + 1] & 0x3F);\n if (ucs4 >= 0x80) {\n out.push(String.fromCharCode(ucs4 & 0xFFFF));\n i += 2;\n continue;\n }\n }\n } else if (input[i] < 0xF0) {\n if (checkContinuation(input, i, 2)) {\n let ucs4 = (input[i] & 0xF) << 12 | (input[i + 1] & 0x3F) << 6 | input[i + 2] & 0x3F;\n if (ucs4 >= 0x800 && (ucs4 & 0xF800) !== 0xD800) {\n out.push(String.fromCharCode(ucs4 & 0xFFFF));\n i += 3;\n continue;\n }\n }\n } else if (input[i] < 0xF8) {\n if (checkContinuation(input, i, 3)) {\n let ucs4 = (input[i] & 0x7) << 18 | (input[i + 1] & 0x3F) << 12\n | (input[i + 2] & 0x3F) << 6 | (input[i + 3] & 0x3F);\n if (ucs4 > 0x10000 && ucs4 < 0x110000) {\n ucs4 -= 0x10000;\n out.push(String.fromCharCode((ucs4 >>> 10) | 0xD800));\n out.push(String.fromCharCode((ucs4 & 0x3FF) | 0xDC00));\n i += 4;\n continue;\n }\n }\n }\n out.push(String.fromCharCode(0xFFFD));\n ++i;\n }\n\n return out.join('');\n}\n\nexport default decodeUTF8;"]} \ No newline at end of file diff --git a/tools/FLV Stream/index.html b/tools/FLV Stream/index.html new file mode 100644 index 0000000..86dc369 --- /dev/null +++ b/tools/FLV Stream/index.html @@ -0,0 +1,36 @@ + + + + + + + FLV to Web Test by Shinobi Systems + + + + + + + + + \ No newline at end of file diff --git a/tools/MP4 Stream/ffmpegToWeb.js b/tools/MP4 Stream/ffmpegToWeb.js new file mode 100644 index 0000000..23edd5f --- /dev/null +++ b/tools/MP4 Stream/ffmpegToWeb.js @@ -0,0 +1,95 @@ +// Shinobi (http://shinobi.video) - FFMPEG MP4 over HTTP Test +// How to Use +// 1. Navigate to directory where this file is. +// 2. Run `npm install express` +// 3. Start with `node ffmpegToWeb.js` +// 4. Get the IP address of the computer where you did step 1. Example : 127.0.0.1 +// 5. Open `http://127.0.0.1:8001/` in your browser. + +var child = require('child_process'); +var events = require('events'); +var express = require('express') +var app = express(); +var server = require('http').Server(app); +var spawn = child.spawn; +var exec = child.exec; +var Emitters = {} +var firstChunks = {} +var config = { + port:8001, + url:'rtsp://131.95.3.162/axis-media/media.3gp' +} +var initEmitter = function(feed){ + if(!Emitters[feed]){ + Emitters[feed] = new events.EventEmitter().setMaxListeners(0) + } + return Emitters[feed] +} +//hold first chunk of FLV video +var initFirstChunk = function(feed,firstBuffer){ + if(!firstChunks[feed]){ + firstChunks[feed] = firstBuffer + } + return firstChunks[feed] +} +console.log('Starting Express Web Server on Port '+config.port) +//start webserver +server.listen(config.port); + +//make libraries static +app.use('/libs',express.static(__dirname + '/../../web/libs')); +app.use('/',express.static(__dirname + '/')); + +//homepage with video element. +//static file send of index.html +app.get('/', function (req, res) { + res.sendFile(__dirname + '/index.html'); +}) + +//// MP4 Stream over HTTP, this URL goes in the flv.js javascript player +// see ./index.html +app.get('/s.mp4', function (req, res) { + //default to first feed + if(!req.params.feed){req.params.feed='1'} + //get emitter + req.Emitter = initEmitter(req.params.feed) + //variable name of contentWriter + var contentWriter + //set headers + res.setHeader('Content-Type', 'video/mp4'); + res.setHeader('Access-Control-Allow-Origin','*'); + //write first frame on stream + res.write(initFirstChunk(1)) + //write new frames as they happen + req.Emitter.on('data',contentWriter=function(buffer){ + console.log(buffer) + res.write(buffer) + }) + //remove contentWriter when client leaves + res.on('close', function () { + req.Emitter.removeListener('data',contentWriter) + }) +}); + +//ffmpeg +console.log('Starting FFMPEG') +var ffmpegString = '-reorder_queue_size 5 -i '+config.url+' -c:v copy -an -movflags +frag_keyframe+empty_moov+default_base_moof -f mp4 pipe:1' +//var ffmpegString = '-i '+config.url+' -c:v libx264 -preset superfast -tune zerolatency -c:a aac -ar 44100 -f flv pipe:4' +//ffmpegString += ' -f mpegts -c:v mpeg1video -an http://localhost:'+config.port+'/streamIn/2' +if(ffmpegString.indexOf('rtsp://')>-1){ + ffmpegString='-rtsp_transport tcp '+ffmpegString +} +console.log('Executing : ffmpeg '+ffmpegString) +var ffmpeg = spawn('ffmpeg',ffmpegString.split(' '),{stdio:['pipe','pipe','pipe','pipe','pipe']}); +ffmpeg.on('close', function (buffer) { + console.log('ffmpeg died') +}) +//// FFMPEG Error Logs +//ffmpeg.stderr.on('data', function (buffer) { +// console.log(buffer.toString()) +//}); +//data from pipe:1 output of ffmpeg +ffmpeg.stdio[1].on('data', function (buffer) { + initFirstChunk(1,buffer) + initEmitter(1).emit('data',buffer) +}); \ No newline at end of file diff --git a/tools/MP4 Stream/flv.min.js b/tools/MP4 Stream/flv.min.js new file mode 100644 index 0000000..94f1ddc --- /dev/null +++ b/tools/MP4 Stream/flv.min.js @@ -0,0 +1,7 @@ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.flvjs=e()}}(function(){var e;return function e(t,n,i){function r(a,o){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!o&&u)return u(a,!0);if(s)return s(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var d=n[a]={exports:{}};t[a][0].call(d.exports,function(e){var n=t[a][1][e];return r(n||e)},d,d.exports,e,t,n,i)}return n[a].exports}for(var s="function"==typeof require&&require,a=0;a0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},i.prototype.on=i.prototype.addListener,i.prototype.once=function(e,t){function n(){this.removeListener(e,n),i||(i=!0,t.apply(this,arguments))}if(!r(t))throw TypeError("listener must be a function");var i=!1;return n.listener=t,this.on(e,n),this},i.prototype.removeListener=function(e,t){var n,i,s,o;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],s=n.length,i=-1,n===t||r(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(a(n)){for(o=s;o-- >0;)if(n[o]===t||n[o].listener&&n[o].listener===t){i=o;break}if(i<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(i,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},i.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],r(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},i.prototype.listeners=function(e){return this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},i.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(r(t))return 1;if(t)return t.length}return 0},i.listenerCount=function(e,t){return e.listenerCount(t)}},{}],3:[function(e,t,n){function i(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function s(e){if(h===setTimeout)return setTimeout(e,0);if((h===i||!h)&&setTimeout)return h=setTimeout,setTimeout(e,0);try{return h(e,0)}catch(t){try{return h.call(null,e,0)}catch(t){return h.call(this,e,0)}}}function a(e){if(f===clearTimeout)return clearTimeout(e);if((f===r||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(e);try{return f(e)}catch(t){try{return f.call(null,e)}catch(t){return f.call(this,e)}}}function o(){p&&_&&(p=!1,_.length?m=_.concat(m):v=-1,m.length&&u())}function u(){if(!p){var e=s(o);p=!0;for(var t=m.length;t;){for(_=m,m=[];++v1)for(var n=1;n=e[r]&&t0&&e[0].originalDts=t[r].dts&&et[i].lastSample.originalDts&&e=t[i].lastSample.originalDts&&(i===t.length-1||i0&&(r=this._searchNearestSegmentBefore(n.originalBeginDts)+1),this._lastAppendLocation=r,this._list.splice(r,0,n)}},{key:"getLastSegmentBefore",value:function(e){var t=this._searchNearestSegmentBefore(e);return t>=0?this._list[t]:null}},{key:"getLastSampleBefore",value:function(e){var t=this.getLastSegmentBefore(e);return null!=t?t.lastSample:null}},{key:"getLastSyncPointBefore",value:function(e){for(var t=this._searchNearestSegmentBefore(e),n=this._list[t].syncPoints;0===n.length&&t>0;)t--,n=this._list[t].syncPoints;return n.length>0?n[n.length-1]:null}},{key:"type",get:function(){return this._type}},{key:"length",get:function(){return this._list.length}}]),e}()},{}],9:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0&&(i+=";codecs="+n.codec);var r=!1;if(l.default.v(this.TAG,"Received Initialization Segment, mimeType: "+i),this._lastInitSegments[n.type]=n,i!==this._mimeTypes[n.type]){if(this._mimeTypes[n.type])l.default.v(this.TAG,"Notice: "+n.type+" mimeType changed, origin: "+this._mimeTypes[n.type]+", target: "+i);else{r=!0;try{var s=this._sourceBuffers[n.type]=this._mediaSource.addSourceBuffer(i);s.addEventListener("error",this.e.onSourceBufferError),s.addEventListener("updateend",this.e.onSourceBufferUpdateEnd)}catch(e){return l.default.e(this.TAG,e.message),void this._emitter.emit(c.default.ERROR,{code:e.code,msg:e.message})}}this._mimeTypes[n.type]=i}t||this._pendingSegments[n.type].push(n),r||this._sourceBuffers[n.type]&&!this._sourceBuffers[n.type].updating&&this._doAppendSegments(),h.default.safari&&"audio/mpeg"===n.container&&n.mediaDuration>0&&(this._requireSetMediaDuration=!0,this._pendingMediaDuration=n.mediaDuration/1e3,this._updateMediaSourceDuration())}},{key:"appendMediaSegment",value:function(e){var t=e;this._pendingSegments[t.type].push(t),this._config.autoCleanupSourceBuffer&&this._needCleanupSourceBuffer()&&this._doCleanupSourceBuffer();var n=this._sourceBuffers[t.type];!n||n.updating||this._hasPendingRemoveRanges()||this._doAppendSegments()}},{key:"seek",value:function(e){for(var t in this._sourceBuffers)if(this._sourceBuffers[t]){var n=this._sourceBuffers[t];if("open"===this._mediaSource.readyState)try{n.abort()}catch(e){l.default.e(this.TAG,e.message)}this._idrList.clear();var i=this._pendingSegments[t];if(i.splice(0,i.length),"closed"!==this._mediaSource.readyState){for(var r=0;r=1&&e-i.start(0)>=this._config.autoCleanupMaxBackwardDuration)return!0}}return!1}},{key:"_doCleanupSourceBuffer",value:function(){var e=this._mediaElement.currentTime;for(var t in this._sourceBuffers){var n=this._sourceBuffers[t];if(n){for(var i=n.buffered,r=!1,s=0;s=this._config.autoCleanupMaxBackwardDuration){r=!0;var u=e-this._config.autoCleanupMinBackwardDuration;this._pendingRemoveRanges[t].push({start:a,end:u})}}else o0&&(isNaN(t)||n>t)&&(l.default.v(this.TAG,"Update MediaSource duration from "+t+" to "+n),this._mediaSource.duration=n),this._requireSetMediaDuration=!1,this._pendingMediaDuration=0}}},{key:"_doRemoveRanges",value:function(){for(var e in this._pendingRemoveRanges)if(this._sourceBuffers[e]&&!this._sourceBuffers[e].updating)for(var t=this._sourceBuffers[e],n=this._pendingRemoveRanges[e];n.length&&!t.updating;){var i=n.shift();t.remove(i.start,i.end)}}},{key:"_doAppendSegments",value:function(){var e=this._pendingSegments;for(var t in e)if(this._sourceBuffers[t]&&!this._sourceBuffers[t].updating&&e[t].length>0){var n=e[t].shift();if(n.timestampOffset){var i=this._sourceBuffers[t].timestampOffset,r=n.timestampOffset/1e3,s=Math.abs(i-r);s>.1&&(l.default.v(this.TAG,"Update MPEG audio timestampOffset from "+i+" to "+r),this._sourceBuffers[t].timestampOffset=r),delete n.timestampOffset}if(!n.data||0===n.data.byteLength)continue;try{this._sourceBuffers[t].appendBuffer(n.data),this._isBufferFull=!1,"video"===t&&n.hasOwnProperty("info")&&this._idrList.appendArray(n.info.syncPoints)}catch(e){this._pendingSegments[t].unshift(n),22===e.code?(this._isBufferFull||this._emitter.emit(c.default.BUFFER_FULL),this._isBufferFull=!0):(l.default.e(this.TAG,e.message),this._emitter.emit(c.default.ERROR,{code:e.code,msg:e.message}))}}}},{key:"_onSourceOpen",value:function(){if(l.default.v(this.TAG,"MediaSource onSourceOpen"),this._mediaSource.removeEventListener("sourceopen",this.e.onSourceOpen),this._pendingSourceBufferInit.length>0)for(var e=this._pendingSourceBufferInit;e.length;){var t=e.shift();this.appendInitSegment(t,!0)}this._hasPendingSegments()&&this._doAppendSegments(),this._emitter.emit(c.default.SOURCE_OPEN)}},{key:"_onSourceEnded",value:function(){l.default.v(this.TAG,"MediaSource onSourceEnded")}},{key:"_onSourceClose",value:function(){l.default.v(this.TAG,"MediaSource onSourceClose"),this._mediaSource&&null!=this.e&&(this._mediaSource.removeEventListener("sourceopen",this.e.onSourceOpen),this._mediaSource.removeEventListener("sourceended",this.e.onSourceEnded),this._mediaSource.removeEventListener("sourceclose",this.e.onSourceClose))}},{key:"_hasPendingSegments",value:function(){var e=this._pendingSegments;return e.video.length>0||e.audio.length>0}},{key:"_hasPendingRemoveRanges",value:function(){var e=this._pendingRemoveRanges;return e.video.length>0||e.audio.length>0}},{key:"_onSourceBufferUpdateEnd",value:function(){this._requireSetMediaDuration?this._updateMediaSourceDuration():this._hasPendingRemoveRanges()?this._doRemoveRanges():this._hasPendingSegments()?this._doAppendSegments():this._hasPendingEos&&this.endOfStream(),this._emitter.emit(c.default.UPDATE_END)}},{key:"_onSourceBufferError",value:function(e){l.default.e(this.TAG,"SourceBuffer Error: "+e)}}]),e}();n.default=p},{"../utils/browser.js":39,"../utils/exception.js":40,"../utils/logger.js":41,"./media-segment-info.js":8,"./mse-events.js":10,events:2}],10:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i={ERROR:"error",SOURCE_OPEN:"source_open",UPDATE_END:"update_end",BUFFER_FULL:"buffer_full"};n.default=i},{}],11:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0)this._demuxer.bindDataSource(this._ioctl),this._demuxer.timestampBase=this._mediaDataSource.segments[this._currentSegmentIndex].timestampBase,r=this._demuxer.parseChunks(e,t);else if((i=m.default.probe(e)).match){this._demuxer=new m.default(i,this._config),this._remuxer||(this._remuxer=new v.default(this._config));var s=this._mediaDataSource;void 0==s.duration||isNaN(s.duration)||(this._demuxer.overridedDuration=s.duration),"boolean"==typeof s.hasAudio&&(this._demuxer.overridedHasAudio=s.hasAudio),"boolean"==typeof s.hasVideo&&(this._demuxer.overridedHasVideo=s.hasVideo),this._demuxer.timestampBase=s.segments[this._currentSegmentIndex].timestampBase,this._demuxer.onError=this._onDemuxException.bind(this),this._demuxer.onMediaInfo=this._onMediaInfo.bind(this),this._remuxer.bindDataSource(this._demuxer.bindDataSource(this._ioctl)),this._remuxer.onInitSegment=this._onRemuxerInitSegmentArrival.bind(this),this._remuxer.onMediaSegment=this._onRemuxerMediaSegmentArrival.bind(this),r=this._demuxer.parseChunks(e,t)}else i=null,l.default.e(this.TAG,"Non-FLV, Unsupported media type!"),Promise.resolve().then(function(){n._internalAbort()}),this._emitter.emit(k.default.DEMUX_ERROR,y.default.FORMAT_UNSUPPORTED,"Non-FLV, Unsupported media type"),r=0;return r}},{key:"_onMediaInfo",value:function(e){var t=this;null==this._mediaInfo&&(this._mediaInfo=Object.assign({},e),this._mediaInfo.keyframesIndex=null,this._mediaInfo.segments=[],this._mediaInfo.segmentCount=this._mediaDataSource.segments.length,Object.setPrototypeOf(this._mediaInfo,c.default.prototype));var n=Object.assign({},e);Object.setPrototypeOf(n,c.default.prototype),this._mediaInfo.segments[this._currentSegmentIndex]=n,this._reportSegmentMediaInfo(this._currentSegmentIndex),null!=this._pendingSeekTime&&Promise.resolve().then(function(){var e=t._pendingSeekTime;t._pendingSeekTime=null,t.seek(e)})}},{key:"_onIOSeeked",value:function(){this._remuxer.insertDiscontinuity()}},{key:"_onIOComplete",value:function(e){var t=e,n=t+1;n0&&n[0].originalDts===i&&(i=n[0].pts),this._emitter.emit(k.default.RECOMMEND_SEEKPOINT,i)}}},{key:"_enableStatisticsReporter",value:function(){null==this._statisticsReporter&&(this._statisticsReporter=self.setInterval(this._reportStatisticsInfo.bind(this),this._config.statisticsInfoReportInterval))}},{key:"_disableStatisticsReporter",value:function(){this._statisticsReporter&&(self.clearInterval(this._statisticsReporter),this._statisticsReporter=null)}},{key:"_reportSegmentMediaInfo",value:function(e){var t=this._mediaInfo.segments[e],n=Object.assign({},t);n.duration=this._mediaInfo.duration,n.segmentCount=this._mediaInfo.segmentCount,delete n.segments,delete n.keyframesIndex,this._emitter.emit(k.default.MEDIA_INFO,n)}},{key:"_reportStatisticsInfo",value:function(){var e={};e.url=this._ioctl.currentURL,e.hasRedirect=this._ioctl.hasRedirect,e.hasRedirect&&(e.redirectedURL=this._ioctl.currentRedirectedURL),e.speed=this._ioctl.currentSpeed,e.loaderType=this._ioctl.loaderType,e.currentSegmentIndex=this._currentSegmentIndex,e.totalSegmentCount=this._mediaDataSource.segments.length,this._emitter.emit(k.default.STATISTICS_INFO,e)}}]),e}());n.default=L},{"../demux/demux-errors.js":16,"../demux/flv-demuxer.js":18,"../io/io-controller.js":23,"../io/loader.js":24,"../remux/mp4-remuxer.js":38,"../utils/browser.js":39,"../utils/logger.js":41,"./media-info.js":7,"./transmuxing-events.js":13,events:2}],13:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i={IO_ERROR:"io_error",DEMUX_ERROR:"demux_error",INIT_SEGMENT:"init_segment",MEDIA_SEGMENT:"media_segment",LOADING_COMPLETE:"loading_complete",RECOVERED_EARLY_EOF:"recovered_early_eof",MEDIA_INFO:"media_info",STATISTICS_INFO:"statistics_info",RECOMMEND_SEEKPOINT:"recommend_seekpoint"};n.default=i},{}],14:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(n,"__esModule",{value:!0});var r=e("../utils/logger.js"),s=(i(r),e("../utils/logging-control.js")),a=i(s),o=e("../utils/polyfill.js"),u=i(o),l=e("./transmuxing-controller.js"),d=i(l),h=e("./transmuxing-events.js"),f=i(h),c=function(e){function t(t,n){var i={msg:f.default.INIT_SEGMENT,data:{type:t,data:n}};e.postMessage(i,[n.data])}function n(t,n){var i={msg:f.default.MEDIA_SEGMENT,data:{type:t,data:n}};e.postMessage(i,[n.data])}function i(){var t={msg:f.default.LOADING_COMPLETE};e.postMessage(t)}function r(){var t={msg:f.default.RECOVERED_EARLY_EOF};e.postMessage(t)}function s(t){var n={msg:f.default.MEDIA_INFO,data:t};e.postMessage(n)}function o(t){var n={msg:f.default.STATISTICS_INFO,data:t};e.postMessage(n)}function l(t,n){e.postMessage({msg:f.default.IO_ERROR,data:{type:t,info:n}})}function h(t,n){e.postMessage({msg:f.default.DEMUX_ERROR,data:{type:t,info:n}})}function c(t){e.postMessage({msg:f.default.RECOMMEND_SEEKPOINT,data:t})}function _(t,n){e.postMessage({msg:"logcat_callback",data:{type:t,logcat:n}})}var m=null,p=_.bind(this);u.default.install(),e.addEventListener("message",function(u){switch(u.data.cmd){case"init":m=new d.default(u.data.param[0],u.data.param[1]),m.on(f.default.IO_ERROR,l.bind(this)),m.on(f.default.DEMUX_ERROR,h.bind(this)),m.on(f.default.INIT_SEGMENT,t.bind(this)),m.on(f.default.MEDIA_SEGMENT,n.bind(this)),m.on(f.default.LOADING_COMPLETE,i.bind(this)),m.on(f.default.RECOVERED_EARLY_EOF,r.bind(this)),m.on(f.default.MEDIA_INFO,s.bind(this)),m.on(f.default.STATISTICS_INFO,o.bind(this)),m.on(f.default.RECOMMEND_SEEKPOINT,c.bind(this));break;case"destroy":m&&(m.destroy(),m=null),e.postMessage({msg:"destroyed"});break;case"start":m.start();break;case"stop":m.stop();break;case"seek":m.seek(u.data.param);break;case"pause":m.pause();break;case"resume":m.resume();break;case"logging_config":var _=u.data.param;a.default.applyConfig(_),!0===_.enableCallback?a.default.addLogListener(p):a.default.removeLogListener(p)}})};n.default=c},{"../utils/logger.js":41,"../utils/logging-control.js":42,"../utils/polyfill.js":43,"./transmuxing-controller.js":12,"./transmuxing-events.js":13}],15:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0?(0,l.default)(new Uint8Array(e,t+2,r)):"",{data:s,size:2+r}}},{key:"parseLongString",value:function(e,t,n){if(n<4)throw new d.IllegalStateException("Data not enough when parse LongString");var i=new DataView(e,t,n),r=i.getUint32(0,!h),s=void 0;return s=r>0?(0,l.default)(new Uint8Array(e,t+4,r)):"",{data:s,size:4+r}}},{key:"parseDate",value:function(e,t,n){if(n<10)throw new d.IllegalStateException("Data size invalid when parse Date");var i=new DataView(e,t,n),r=i.getFloat64(0,!h);return r+=60*i.getInt16(8,!h)*1e3,{data:new Date(r),size:10}}},{key:"parseValue",value:function(t,n,i){if(i<1)throw new d.IllegalStateException("Data not enough when parse Value");var r=new DataView(t,n,i),s=1,a=r.getUint8(0),u=void 0,l=!1;try{switch(a){case 0:u=r.getFloat64(1,!h),s+=8;break;case 1:u=!!r.getUint8(1),s+=1;break;case 2:var f=e.parseString(t,n+1,i-1);u=f.data,s+=f.size;break;case 3:u={};var c=0;for(9==(16777215&r.getUint32(i-4,!h))&&(c=3);s32)throw new s.InvalidArgumentException("ExpGolomb: readBits() bits exceeded max 32bits!");if(e<=this._current_word_bits_left){var t=this._current_word>>>32-e;return this._current_word<<=e,this._current_word_bits_left-=e,t}var n=this._current_word_bits_left?this._current_word:0;n>>>=32-this._current_word_bits_left;var i=e-this._current_word_bits_left;this._fillCurrentWord();var r=Math.min(i,this._current_word_bits_left),a=this._current_word>>>32-r;return this._current_word<<=r,this._current_word_bits_left-=r,n=n<>>e))return this._current_word<<=e,this._current_word_bits_left-=e,e;return this._fillCurrentWord(),e+this._skipLeadingZero()}},{key:"readUEG",value:function(){var e=this._skipLeadingZero();return this.readBits(e+1)-1}},{key:"readSEG",value:function(){var e=this.readUEG();return 1&e?e+1>>>1:-1*(e>>>1)}}]),e}();n.default=a},{"../utils/exception.js":40}],18:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]}Object.defineProperty(n,"__esModule",{value:!0});var a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=function(){function e(e,t){for(var n=0;n13))return 0;i=e.probe(t).dataOffset}if(this._firstParse){this._firstParse=!1,n+i!==this._dataOffset&&l.default.w(this.TAG,"First time parsing but chunk byteStart invalid!");0!==new DataView(t,i).getUint32(0,!r)&&l.default.w(this.TAG,"PrevTagSize0 !== 0 !!!"),i+=4}for(;it.byteLength)break;var a=s.getUint8(0),o=16777215&s.getUint32(0,!r);if(i+11+o+4>t.byteLength)break;if(8===a||9===a||18===a){var u=s.getUint8(4),d=s.getUint8(5),h=s.getUint8(6),f=s.getUint8(7),c=h|d<<8|u<<16|f<<24;0!==(16777215&s.getUint32(7,!r))&&l.default.w(this.TAG,"Meet tag which has StreamID != 0!");var _=i+11;switch(a){case 8:this._parseAudioData(t,_,o,c);break;case 9:this._parseVideoData(t,_,o,c,n+i);break;case 18:this._parseScriptData(t,_,o)}var m=s.getUint32(11+o,!r);m!==11+o&&l.default.w(this.TAG,"Invalid PrevTagSize "+m),i+=11+o+4}else l.default.w(this.TAG,"Unsupported tag type "+a+", skipped"),i+=11+o+4}return this._isInitialMetadataDispatched()&&this._dispatch&&(this._audioTrack.length||this._videoTrack.length)&&this._onDataAvailable(this._audioTrack,this._videoTrack),i}},{key:"_parseScriptData",value:function(e,t,n){var i=h.default.parseScriptData(e,t,n);if(i.hasOwnProperty("onMetaData")){if(null==i.onMetaData||"object"!==a(i.onMetaData))return void l.default.w(this.TAG,"Invalid onMetaData structure!");this._metadata&&l.default.w(this.TAG,"Found another onMetaData tag!"),this._metadata=i;var r=this._metadata.onMetaData;if("boolean"==typeof r.hasAudio&&!1===this._hasAudioFlagOverrided&&(this._hasAudio=r.hasAudio,this._mediaInfo.hasAudio=this._hasAudio),"boolean"==typeof r.hasVideo&&!1===this._hasVideoFlagOverrided&&(this._hasVideo=r.hasVideo,this._mediaInfo.hasVideo=this._hasVideo),"number"==typeof r.audiodatarate&&(this._mediaInfo.audioDataRate=r.audiodatarate),"number"==typeof r.videodatarate&&(this._mediaInfo.videoDataRate=r.videodatarate),"number"==typeof r.width&&(this._mediaInfo.width=r.width),"number"==typeof r.height&&(this._mediaInfo.height=r.height),"number"==typeof r.duration){if(!this._durationOverrided){var s=Math.floor(r.duration*this._timescale);this._duration=s,this._mediaInfo.duration=s}}else this._mediaInfo.duration=0;if("number"==typeof r.framerate){var o=Math.floor(1e3*r.framerate);if(o>0){var u=o/1e3;this._referenceFrameRate.fixed=!0,this._referenceFrameRate.fps=u,this._referenceFrameRate.fps_num=o,this._referenceFrameRate.fps_den=1e3,this._mediaInfo.fps=u}}if("object"===a(r.keyframes)){this._mediaInfo.hasKeyframesIndex=!0;var d=r.keyframes;this._mediaInfo.keyframesIndex=this._parseKeyframesIndex(d),r.keyframes=null}else this._mediaInfo.hasKeyframesIndex=!1;this._dispatch=!1,this._mediaInfo.metadata=r,l.default.v(this.TAG,"Parsed onMetaData"),this._mediaInfo.isComplete()&&this._onMediaInfo(this._mediaInfo)}}},{key:"_parseKeyframesIndex",value:function(e){for(var t=[],n=[],i=1;i>>4;if(2!==a&&10!==a)return void this._onError(m.default.CODEC_UNSUPPORTED,"Flv: Unsupported audio codec idx: "+a);var o=0,u=(12&s)>>>2;if(!(u>=0&&u<=4))return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid audio sample rate idx: "+u);o=this._flvSoundRateTable[u];var d=1&s,h=this._audioMetadata,f=this._audioTrack;if(h||(!1===this._hasAudio&&!1===this._hasAudioFlagOverrided&&(this._hasAudio=!0,this._mediaInfo.hasAudio=!0),h=this._audioMetadata={},h.type="audio",h.id=f.id,h.timescale=this._timescale,h.duration=this._duration,h.audioSampleRate=o,h.channelCount=0===d?1:2),10===a){var c=this._parseAACAudioData(e,t+1,n-1);if(void 0==c)return;if(0===c.packetType){h.config&&l.default.w(this.TAG,"Found another AudioSpecificConfig!");var _=c.data;h.audioSampleRate=_.samplingRate,h.channelCount=_.channelCount,h.codec=_.codec,h.originalCodec=_.originalCodec,h.config=_.config,h.refSampleDuration=1024/h.audioSampleRate*h.timescale,l.default.v(this.TAG,"Parsed AudioSpecificConfig"),this._isInitialMetadataDispatched()?this._dispatch&&(this._audioTrack.length||this._videoTrack.length)&&this._onDataAvailable(this._audioTrack,this._videoTrack):this._audioInitialMetadataDispatched=!0,this._dispatch=!1,this._onTrackMetadata("audio",h);var p=this._mediaInfo;p.audioCodec=h.originalCodec,p.audioSampleRate=h.audioSampleRate,p.audioChannelCount=h.channelCount,p.hasVideo?null!=p.videoCodec&&(p.mimeType='video/x-flv; codecs="'+p.videoCodec+","+p.audioCodec+'"'):p.mimeType='video/x-flv; codecs="'+p.audioCodec+'"',p.isComplete()&&this._onMediaInfo(p)}else if(1===c.packetType){var v=this._timestampBase+i,g={unit:c.data,dts:v,pts:v};f.samples.push(g),f.length+=c.data.length}else l.default.e(this.TAG,"Flv: Unsupported AAC data type "+c.packetType)}else if(2===a){if(!h.codec){var y=this._parseMP3AudioData(e,t+1,n-1,!0);if(void 0==y)return;h.audioSampleRate=y.samplingRate,h.channelCount=y.channelCount,h.codec=y.codec,h.originalCodec=y.originalCodec,h.refSampleDuration=1152/h.audioSampleRate*h.timescale,l.default.v(this.TAG,"Parsed MPEG Audio Frame Header"),this._audioInitialMetadataDispatched=!0,this._onTrackMetadata("audio",h);var E=this._mediaInfo;E.audioCodec=h.codec,E.audioSampleRate=h.audioSampleRate,E.audioChannelCount=h.channelCount,E.audioDataRate=y.bitRate,E.hasVideo?null!=E.videoCodec&&(E.mimeType='video/x-flv; codecs="'+E.videoCodec+","+E.audioCodec+'"'):E.mimeType='video/x-flv; codecs="'+E.audioCodec+'"',E.isComplete()&&this._onMediaInfo(E)}var b=this._parseMP3AudioData(e,t+1,n-1,!1);if(void 0==b)return;var S=this._timestampBase+i,k={unit:b,dts:S,pts:S};f.samples.push(k),f.length+=b.length}}}},{ +key:"_parseAACAudioData",value:function(e,t,n){if(n<=1)return void l.default.w(this.TAG,"Flv: Invalid AAC packet, missing AACPacketType or/and Data!");var i={},r=new Uint8Array(e,t,n);return i.packetType=r[0],0===r[0]?i.data=this._parseAACAudioSpecificConfig(e,t+1,n-1):i.data=r.subarray(1),i}},{key:"_parseAACAudioSpecificConfig",value:function(e,t,n){var i=new Uint8Array(e,t,n),r=null,s=0,a=0,o=0,u=null;if(s=a=i[0]>>>3,(o=(7&i[0])<<1|i[1]>>>7)<0||o>=this._mpegSamplingRates.length)return void this._onError(m.default.FORMAT_ERROR,"Flv: AAC invalid sampling frequency index!");var l=this._mpegSamplingRates[o],d=(120&i[1])>>>3;if(d<0||d>=8)return void this._onError(m.default.FORMAT_ERROR,"Flv: AAC invalid channel configuration");5===s&&(u=(7&i[1])<<1|i[2]>>>7,i[2]);var h=self.navigator.userAgent.toLowerCase();return-1!==h.indexOf("firefox")?o>=6?(s=5,r=new Array(4),u=o-3):(s=2,r=new Array(2),u=o):-1!==h.indexOf("android")?(s=2,r=new Array(2),u=o):(s=5,u=o,r=new Array(4),o>=6?u=o-3:1===d&&(s=2,r=new Array(2),u=o)),r[0]=s<<3,r[0]|=(15&o)>>>1,r[1]=(15&o)<<7,r[1]|=(15&d)<<3,5===s&&(r[1]|=(15&u)>>>1,r[2]=(1&u)<<7,r[2]|=8,r[3]=0),{config:r,samplingRate:l,channelCount:d,codec:"mp4a.40."+s,originalCodec:"mp4a.40."+a}}},{key:"_parseMP3AudioData",value:function(e,t,n,i){if(n<4)return void l.default.w(this.TAG,"Flv: Invalid MP3 packet, header missing!");var r=(this._littleEndian,new Uint8Array(e,t,n)),s=null;if(i){if(255!==r[0])return;var a=r[1]>>>3&3,o=(6&r[1])>>1,u=(240&r[2])>>>4,d=(12&r[2])>>>2,h=r[3]>>>6&3,f=3!==h?2:1,c=0,_=0;switch(a){case 0:c=this._mpegAudioV25SampleRateTable[d];break;case 2:c=this._mpegAudioV20SampleRateTable[d];break;case 3:c=this._mpegAudioV10SampleRateTable[d]}switch(o){case 1:34,u>>4,o=15&s;if(7!==o)return void this._onError(m.default.CODEC_UNSUPPORTED,"Flv: Unsupported codec in video frame: "+o);this._parseAVCVideoPacket(e,t+1,n-1,i,r,a)}}},{key:"_parseAVCVideoPacket",value:function(e,t,n,i,r,s){if(n<4)return void l.default.w(this.TAG,"Flv: Invalid AVC packet, missing AVCPacketType or/and CompositionTime");var a=this._littleEndian,o=new DataView(e,t,n),u=o.getUint8(0),d=16777215&o.getUint32(0,!a);if(0===u)this._parseAVCDecoderConfigurationRecord(e,t+4,n-4);else if(1===u)this._parseAVCVideoData(e,t+4,n-4,i,r,s,d);else if(2!==u)return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid video packet type "+u)}},{key:"_parseAVCDecoderConfigurationRecord",value:function(e,t,n){if(n<7)return void l.default.w(this.TAG,"Flv: Invalid AVCDecoderConfigurationRecord, lack of data!");var i=this._videoMetadata,r=this._videoTrack,s=this._littleEndian,a=new DataView(e,t,n);i?void 0!==i.avcc&&l.default.w(this.TAG,"Found another AVCDecoderConfigurationRecord!"):(!1===this._hasVideo&&!1===this._hasVideoFlagOverrided&&(this._hasVideo=!0,this._mediaInfo.hasVideo=!0),i=this._videoMetadata={},i.type="video",i.id=r.id,i.timescale=this._timescale,i.duration=this._duration);var o=a.getUint8(0),u=a.getUint8(1);a.getUint8(2),a.getUint8(3);if(1!==o||0===u)return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid AVCDecoderConfigurationRecord");if(this._naluLengthSize=1+(3&a.getUint8(4)),3!==this._naluLengthSize&&4!==this._naluLengthSize)return void this._onError(m.default.FORMAT_ERROR,"Flv: Strange NaluLengthSizeMinusOne: "+(this._naluLengthSize-1));var d=31&a.getUint8(5);if(0===d)return void this._onError(m.default.FORMAT_ERROR,"Flv: Invalid AVCDecoderConfigurationRecord: No SPS");d>1&&l.default.w(this.TAG,"Flv: Strange AVCDecoderConfigurationRecord: SPS Count = "+d);for(var h=6,f=0;f1&&l.default.w(this.TAG,"Flv: Strange AVCDecoderConfigurationRecord: PPS Count = "+w),h++;for(var R=0;R=n){l.default.w(this.TAG,"Malformed Nalu near timestamp "+_+", offset = "+f+", dataSize = "+n);break}var p=u.getUint32(f,!o);if(3===c&&(p>>>=8),p>n-c)return void l.default.w(this.TAG,"Malformed Nalus near timestamp "+_+", NaluSize > DataSize!");var v=31&u.getUint8(f+c);5===v&&(m=!0);var g=new Uint8Array(e,t+f,c+p),y={type:v,data:g};d.push(y),h+=g.byteLength,f+=c+p}if(d.length){var E=this._videoTrack,b={units:d,length:h,isKeyframe:m,dts:_,cts:a,pts:_+a};m&&(b.fileposition=r),E.samples.push(b),E.length+=h}}},{key:"onTrackMetadata",get:function(){return this._onTrackMetadata},set:function(e){this._onTrackMetadata=e}},{key:"onMediaInfo",get:function(){return this._onMediaInfo},set:function(e){this._onMediaInfo=e}},{key:"onError",get:function(){return this._onError},set:function(e){this._onError=e}},{key:"onDataAvailable",get:function(){return this._onDataAvailable},set:function(e){this._onDataAvailable=e}},{key:"timestampBase",get:function(){return this._timestampBase},set:function(e){this._timestampBase=e}},{key:"overridedDuration",get:function(){return this._duration},set:function(e){this._durationOverrided=!0,this._duration=e,this._mediaInfo.duration=e}},{key:"overridedHasAudio",set:function(e){this._hasAudioFlagOverrided=!0,this._hasAudio=e,this._mediaInfo.hasAudio=e}},{key:"overridedHasVideo",set:function(e){this._hasVideoFlagOverrided=!0,this._hasVideo=e,this._mediaInfo.hasVideo=e}}],[{key:"probe",value:function(e){var t=new Uint8Array(e),n={match:!1};if(70!==t[0]||76!==t[1]||86!==t[2]||1!==t[3])return n;var i=(4&t[4])>>>2!=0,r=0!=(1&t[4]),a=s(t,5);return a<9?n:{match:!0,consumed:a,dataOffset:a,hasAudioTrack:i,hasVideoTrack:r}}}]),e}();n.default=y},{"../core/media-info.js":7,"../utils/exception.js":40,"../utils/logger.js":41,"./amf-parser.js":15,"./demux-errors.js":16,"./sps-parser.js":19}],19:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=2&&3===t[s]&&0===t[s-1]&&0===t[s-2]||(i[r]=t[s],r++);return new Uint8Array(i.buffer,0,r)}},{key:"parseSPS",value:function(t){var n=e._ebsp2rbsp(t),i=new a.default(n);i.readByte();var r=i.readByte();i.readByte();var s=i.readByte();i.readUEG();var o=e.getProfileString(r),u=e.getLevelString(s),l=1,d=420,h=[0,420,422,444],f=8;if((100===r||110===r||122===r||244===r||44===r||83===r||86===r||118===r||128===r||138===r||144===r)&&(l=i.readUEG(),3===l&&i.readBits(1),l<=3&&(d=h[l]),f=i.readUEG()+8,i.readUEG(),i.readBits(1),i.readBool()))for(var c=3!==l?8:12,_=0;_0&&I<16?(w=x[I-1],R=M[I-1]):255===I&&(w=i.readByte()<<8|i.readByte(),R=i.readByte()<<8|i.readByte())}if(i.readBool()&&i.readBool(),i.readBool()&&(i.readBits(4),i.readBool()&&i.readBits(24)),i.readBool()&&(i.readUEG(),i.readUEG()),i.readBool()){var D=i.readBits(32),B=i.readBits(32);O=i.readBool(),T=B,C=2*D,A=T/C}}var j=1;1===w&&1===R||(j=w/R);var P=0,U=0;if(0===l)P=1,U=2-E;else{var N=3===l?1:2,F=1===l?2:1;P=N,U=F*(2-E)}var G=16*(g+1),V=16*(y+1)*(2-E);G-=(b+S)*P,V-=(k+L)*U;var z=Math.ceil(G*j);return i.destroy(),i=null,{profile_string:o,level_string:u,bit_depth:f,chroma_format:d,chroma_format_string:e.getChromaFormatString(d),frame_rate:{fixed:O,fps:A,fps_den:C,fps_num:T},sar_ratio:{width:w,height:R},codec_size:{width:G,height:V},present_size:{width:z,height:V}}}},{key:"_skipScalingList",value:function(e,t){for(var n=8,i=8,r=0,s=0;s=15048,t=!f.default.msedge||e;return self.fetch&&self.ReadableStream&&t}catch(e){return!1}}}]),l(t,[{key:"destroy",value:function(){this.isWorking()&&this.abort(),u(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"destroy",this).call(this)}},{key:"open",value:function(e,t){var n=this;this._dataSource=e,this._range=t;var i=e.url;this._config.reuseRedirectedURL&&void 0!=e.redirectedURL&&(i=e.redirectedURL);var r=this._seekHandler.getConfig(i,t),s=new self.Headers;if("object"===o(r.headers)){var a=r.headers;for(var u in a)a.hasOwnProperty(u)&&s.append(u,a[u])}var l={method:"GET",headers:s,mode:"cors",cache:"default",referrerPolicy:"no-referrer-when-downgrade"};!1===e.cors&&(l.mode="same-origin"),e.withCredentials&&(l.credentials="include"),e.referrerPolicy&&(l.referrerPolicy=e.referrerPolicy),this._status=c.LoaderStatus.kConnecting,self.fetch(r.url,l).then(function(e){if(n._requestAbort)return n._requestAbort=!1,void(n._status=c.LoaderStatus.kIdle);if(e.ok&&e.status>=200&&e.status<=299){if(e.url!==r.url&&n._onURLRedirect){var t=n._seekHandler.removeURLParameters(e.url);n._onURLRedirect(t)}var i=e.headers.get("Content-Length");return null!=i&&(n._contentLength=parseInt(i),0!==n._contentLength&&n._onContentLengthKnown&&n._onContentLengthKnown(n._contentLength)),n._pump.call(n,e.body.getReader())}if(n._status=c.LoaderStatus.kError,!n._onError)throw new _.RuntimeException("FetchStreamLoader: Http code invalid, "+e.status+" "+e.statusText);n._onError(c.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:e.status,msg:e.statusText})}).catch(function(e){if(n._status=c.LoaderStatus.kError,!n._onError)throw e;n._onError(c.LoaderErrors.EXCEPTION,{code:-1,msg:e.message})})}},{key:"abort",value:function(){this._requestAbort=!0}},{key:"_pump",value:function(e){var t=this;return e.read().then(function(n){if(n.done)t._status=c.LoaderStatus.kComplete,t._onComplete&&t._onComplete(t._range.from,t._range.from+t._receivedLength-1);else{if(!0===t._requestAbort)return t._requestAbort=!1,t._status=c.LoaderStatus.kComplete,e.cancel();t._status=c.LoaderStatus.kBuffering;var i=n.value.buffer,r=t._range.from+t._receivedLength;t._receivedLength+=i.byteLength,t._onDataArrival&&t._onDataArrival(i,r,t._receivedLength),t._pump(e)}}).catch(function(e){if(11!==e.code||!f.default.msedge){t._status=c.LoaderStatus.kError;var n=0,i=null;if(19!==e.code&&"network error"!==e.message||!(null===t._contentLength||null!==t._contentLength&&t._receivedLength0&&(this._stashInitialSize=n.stashInitialSize),this._stashUsed=0,this._stashSize=this._stashInitialSize,this._bufferSize=3145728,this._stashBuffer=new ArrayBuffer(this._bufferSize),this._stashByteStart=0,this._enableStash=!0,!1===n.enableStashBuffer&&(this._enableStash=!1),this._loader=null,this._loaderClass=null,this._seekHandler=null,this._dataSource=t,this._isWebSocketURL=/wss?:\/\/(.+?)/.test(t.url),this._refTotalLength=t.filesize?t.filesize:null,this._totalLength=this._refTotalLength,this._fullRequestFlag=!1,this._currentRange=null,this._redirectedURL=null,this._speedNormalized=0,this._speedSampler=new l.default,this._speedNormalizeList=[64,128,256,384,512,768,1024,1536,2048,3072,4096],this._isEarlyEofReconnecting=!1,this._paused=!1,this._resumeFrom=0,this._onDataArrival=null,this._onSeeked=null,this._onError=null,this._onComplete=null,this._onRedirect=null,this._onRecoveredEarlyEof=null,this._selectSeekHandler(),this._selectLoader(),this._createLoader()}return s(e,[{key:"destroy",value:function(){this._loader.isWorking()&&this._loader.abort(),this._loader.destroy(),this._loader=null,this._loaderClass=null,this._dataSource=null,this._stashBuffer=null,this._stashUsed=this._stashSize=this._bufferSize=this._stashByteStart=0,this._currentRange=null,this._speedSampler=null,this._isEarlyEofReconnecting=!1,this._onDataArrival=null,this._onSeeked=null,this._onError=null,this._onComplete=null,this._onRedirect=null,this._onRecoveredEarlyEof=null,this._extraData=null}},{key:"isWorking",value:function(){return this._loader&&this._loader.isWorking()&&!this._paused}},{key:"isPaused",value:function(){return this._paused}},{key:"_selectSeekHandler",value:function(){var e=this._config;if("range"===e.seekType)this._seekHandler=new b.default(this._config.rangeLoadZeroStart);else if("param"===e.seekType){var t=e.seekParamStart||"bstart",n=e.seekParamEnd||"bend";this._seekHandler=new k.default(t,n)}else{if("custom"!==e.seekType)throw new L.InvalidArgumentException("Invalid seekType in config: "+e.seekType);if("function"!=typeof e.customSeekHandler)throw new L.InvalidArgumentException("Custom seekType specified in config but invalid customSeekHandler!");this._seekHandler=new e.customSeekHandler}}},{key:"_selectLoader",value:function(){if(this._isWebSocketURL)this._loaderClass=y.default;else if(f.default.isSupported())this._loaderClass=f.default;else if(_.default.isSupported())this._loaderClass=_.default;else{if(!v.default.isSupported())throw new L.RuntimeException("Your browser doesn't support xhr with arraybuffer responseType!");this._loaderClass=v.default}}},{key:"_createLoader",value:function(){this._loader=new this._loaderClass(this._seekHandler,this._config),!1===this._loader.needStashBuffer&&(this._enableStash=!1),this._loader.onContentLengthKnown=this._onContentLengthKnown.bind(this),this._loader.onURLRedirect=this._onURLRedirect.bind(this),this._loader.onDataArrival=this._onLoaderChunkArrival.bind(this),this._loader.onComplete=this._onLoaderComplete.bind(this),this._loader.onError=this._onLoaderError.bind(this)}},{key:"open",value:function(e){this._currentRange={from:0,to:-1},e&&(this._currentRange.from=e),this._speedSampler.reset(),e||(this._fullRequestFlag=!0),this._loader.open(this._dataSource,Object.assign({},this._currentRange))}},{key:"abort",value:function(){this._loader.abort(),this._paused&&(this._paused=!1,this._resumeFrom=0)}},{key:"pause",value:function(){this.isWorking()&&(this._loader.abort(),0!==this._stashUsed?(this._resumeFrom=this._stashByteStart,this._currentRange.to=this._stashByteStart-1):this._resumeFrom=this._currentRange.to+1,this._stashUsed=0,this._stashByteStart=0,this._paused=!0)}},{key:"resume",value:function(){if(this._paused){this._paused=!1;var e=this._resumeFrom;this._resumeFrom=0,this._internalSeek(e,!0)}}},{key:"seek",value:function(e){this._paused=!1,this._stashUsed=0,this._stashByteStart=0,this._internalSeek(e,!0)}},{key:"_internalSeek",value:function(e,t){this._loader.isWorking()&&this._loader.abort(),this._flushStashBuffer(t),this._loader.destroy(),this._loader=null;var n={from:e,to:-1};this._currentRange={from:n.from,to:-1},this._speedSampler.reset(),this._stashSize=this._stashInitialSize,this._createLoader(),this._loader.open(this._dataSource,n),this._onSeeked&&this._onSeeked()}},{key:"updateUrl",value:function(e){if(!e||"string"!=typeof e||0===e.length)throw new L.InvalidArgumentException("Url must be a non-empty string!");this._dataSource.url=e}},{key:"_expandBuffer",value:function(e){for(var t=this._stashSize;t+10485760){var i=new Uint8Array(this._stashBuffer,0,this._stashUsed);new Uint8Array(n,0,t).set(i,0)}this._stashBuffer=n,this._bufferSize=t}}},{key:"_normalizeSpeed",value:function(e){var t=this._speedNormalizeList,n=t.length-1,i=0,r=0,s=n;if(e=t[i]&&e=512&&e<=1024?Math.floor(1.5*e):2*e)>8192&&(t=8192);var n=1024*t+1048576;this._bufferSize0){var o=this._stashBuffer.slice(0,this._stashUsed),u=this._dispatchChunks(o,this._stashByteStart);if(u0){var l=new Uint8Array(o,u);a.set(l,0),this._stashUsed=l.byteLength,this._stashByteStart+=u}}else this._stashUsed=0,this._stashByteStart+=u;this._stashUsed+e.byteLength>this._bufferSize&&(this._expandBuffer(this._stashUsed+e.byteLength),a=new Uint8Array(this._stashBuffer,0,this._bufferSize)),a.set(new Uint8Array(e),this._stashUsed),this._stashUsed+=e.byteLength}else{var d=this._dispatchChunks(e,t);if(dthis._bufferSize&&(this._expandBuffer(h),a=new Uint8Array(this._stashBuffer,0,this._bufferSize)),a.set(new Uint8Array(e,d),0),this._stashUsed+=h,this._stashByteStart=t+d}}}else if(0===this._stashUsed){var f=this._dispatchChunks(e,t);if(fthis._bufferSize&&this._expandBuffer(c);var _=new Uint8Array(this._stashBuffer,0,this._bufferSize);_.set(new Uint8Array(e,f),0),this._stashUsed+=c,this._stashByteStart=t+f}}else{this._stashUsed+e.byteLength>this._bufferSize&&this._expandBuffer(this._stashUsed+e.byteLength);var m=new Uint8Array(this._stashBuffer,0,this._bufferSize);m.set(new Uint8Array(e),this._stashUsed),this._stashUsed+=e.byteLength;var p=this._dispatchChunks(this._stashBuffer.slice(0,this._stashUsed),this._stashByteStart);if(p0){var v=new Uint8Array(this._stashBuffer,p);m.set(v,0)}this._stashUsed-=p,this._stashByteStart+=p}}}},{key:"_flushStashBuffer",value:function(e){if(this._stashUsed>0){var t=this._stashBuffer.slice(0,this._stashUsed),n=this._dispatchChunks(t,this._stashByteStart),i=t.byteLength-n;if(n0){var r=new Uint8Array(this._stashBuffer,0,this._bufferSize),s=new Uint8Array(t,n);r.set(s,0),this._stashUsed=s.byteLength,this._stashByteStart+=n}return 0}o.default.w(this.TAG,i+" bytes unconsumed data remain when flush buffer, dropped")}return this._stashUsed=0,this._stashByteStart=0,i}return 0}},{key:"_onLoaderComplete",value:function(e,t){this._flushStashBuffer(!0),this._onComplete&&this._onComplete(this._extraData)}},{key:"_onLoaderError",value:function(e,t){switch(o.default.e(this.TAG,"Loader error, code = "+t.code+", msg = "+t.msg),this._flushStashBuffer(!1),this._isEarlyEofReconnecting&&(this._isEarlyEofReconnecting=!1,e=d.LoaderErrors.UNRECOVERABLE_EARLY_EOF),e){case d.LoaderErrors.EARLY_EOF:if(!this._config.isLive&&this._totalLength){var n=this._currentRange.to+1;return void(n0)for(var s=n.split("&"),a=0;a0;o[0]!==this._startName&&o[0]!==this._endName&&(u&&(r+="&"),r+=s[a])}return 0===r.length?t:t+"?"+r}}]),e}();n.default=s},{}],26:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=500?this.currentKBps:0}},{key:"averageKBps",get:function(){var e=(this._now()-this._firstCheckpoint)/1e3;return this._totalBytes/e/1024}}]),e}();n.default=s},{}],28:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(n,"__esModule",{value:!0});var a=function e(t,n,i){null===t&&(t=Function.prototype);var r=Object.getOwnPropertyDescriptor(t,n);if(void 0===r){var s=Object.getPrototypeOf(t);return null===s?void 0:e(s,n,i)}if("value"in r)return r.value;var a=r.get;if(void 0!==a)return a.call(i)},o=function(){function e(e,t){for(var n=0;n299)){if(this._status=h.LoaderStatus.kError,!this._onError)throw new f.RuntimeException("MozChunkedLoader: Http code invalid, "+t.status+" "+t.statusText);this._onError(h.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:t.status,msg:t.statusText})}else this._status=h.LoaderStatus.kBuffering}}},{key:"_onProgress",value:function(e){if(this._status!==h.LoaderStatus.kError){null===this._contentLength&&null!==e.total&&0!==e.total&&(this._contentLength=e.total,this._onContentLengthKnown&&this._onContentLengthKnown(this._contentLength));var t=e.target.response,n=this._range.from+this._receivedLength;this._receivedLength+=t.byteLength,this._onDataArrival&&this._onDataArrival(t,n,this._receivedLength)}}},{key:"_onLoadEnd",value:function(e){if(!0===this._requestAbort)return void(this._requestAbort=!1);this._status!==h.LoaderStatus.kError&&(this._status=h.LoaderStatus.kComplete,this._onComplete&&this._onComplete(this._range.from,this._range.from+this._receivedLength-1))}},{key:"_onXhrError",value:function(e){this._status=h.LoaderStatus.kError;var t=0,n=null;if(this._contentLength&&e.loaded=200&&t.status<=299){if(this._status=h.LoaderStatus.kBuffering,void 0!=t.responseURL){var n=this._seekHandler.removeURLParameters(t.responseURL);t.responseURL!==this._currentRequestURL&&n!==this._currentRedirectedURL&&(this._currentRedirectedURL=n,this._onURLRedirect&&this._onURLRedirect(n))}var i=t.getResponseHeader("Content-Length");if(null!=i&&null==this._contentLength){var r=parseInt(i);r>0&&(this._contentLength=r,this._onContentLengthKnown&&this._onContentLengthKnown(this._contentLength))}}else{if(this._status=h.LoaderStatus.kError,!this._onError)throw new f.RuntimeException("MSStreamLoader: Http code invalid, "+t.status+" "+t.statusText);this._onError(h.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:t.status,msg:t.statusText})}else if(3===t.readyState&&t.status>=200&&t.status<=299){this._status=h.LoaderStatus.kBuffering;var s=t.response;this._reader.readAsArrayBuffer(s)}}},{key:"_xhrOnError",value:function(e){this._status=h.LoaderStatus.kError;var t=h.LoaderErrors.EXCEPTION,n={code:-1,msg:e.constructor.name+" "+e.type};if(!this._onError)throw new f.RuntimeException(n.msg);this._onError(t,n)}},{key:"_msrOnProgress",value:function(e){var t=e.target,n=t.result;if(null==n)return void this._doReconnectIfNeeded();var i=n.slice(this._lastTimeBufferSize);this._lastTimeBufferSize=n.byteLength;var r=this._totalRange.from+this._receivedLength;this._receivedLength+=i.byteLength,this._onDataArrival&&this._onDataArrival(i,r,this._receivedLength),n.byteLength>=this._bufferLimit&&(d.default.v(this.TAG,"MSStream buffer exceeded max size near "+(r+i.byteLength)+", reconnecting..."),this._doReconnectIfNeeded())}},{key:"_doReconnectIfNeeded",value:function(){if(null==this._contentLength||this._receivedLength=this._contentLength&&(n=this._range.from+this._contentLength-1),this._currentRequestRange={from:t,to:n},this._internalOpen(this._dataSource,this._currentRequestRange)}},{key:"_internalOpen",value:function(e,t){this._lastTimeLoaded=0;var n=e.url;this._config.reuseRedirectedURL&&(void 0!=this._currentRedirectedURL?n=this._currentRedirectedURL:void 0!=e.redirectedURL&&(n=e.redirectedURL));var i=this._seekHandler.getConfig(n,t);this._currentRequestURL=i.url;var r=this._xhr=new XMLHttpRequest;if(r.open("GET",i.url,!0),r.responseType="arraybuffer",r.onreadystatechange=this._onReadyStateChange.bind(this),r.onprogress=this._onProgress.bind(this),r.onload=this._onLoad.bind(this),r.onerror=this._onXhrError.bind(this),e.withCredentials&&r.withCredentials&&(r.withCredentials=!0),"object"===o(i.headers)){var s=i.headers;for(var a in s)s.hasOwnProperty(a)&&r.setRequestHeader(a,s[a])}r.send()}},{key:"abort",value:function(){this._requestAbort=!0,this._internalAbort(),this._status=_.LoaderStatus.kComplete}},{key:"_internalAbort",value:function(){this._xhr&&(this._xhr.onreadystatechange=null,this._xhr.onprogress=null,this._xhr.onload=null,this._xhr.onerror=null,this._xhr.abort(),this._xhr=null)}},{key:"_onReadyStateChange",value:function(e){var t=e.target;if(2===t.readyState){if(void 0!=t.responseURL){var n=this._seekHandler.removeURLParameters(t.responseURL);t.responseURL!==this._currentRequestURL&&n!==this._currentRedirectedURL&&(this._currentRedirectedURL=n,this._onURLRedirect&&this._onURLRedirect(n))}if(t.status>=200&&t.status<=299){if(this._waitForTotalLength)return;this._status=_.LoaderStatus.kBuffering}else{if(this._status=_.LoaderStatus.kError,!this._onError)throw new m.RuntimeException("RangeLoader: Http code invalid, "+t.status+" "+t.statusText);this._onError(_.LoaderErrors.HTTP_STATUS_CODE_INVALID,{code:t.status,msg:t.statusText})}}}},{key:"_onProgress",value:function(e){if(this._status!==_.LoaderStatus.kError){if(null===this._contentLength){var t=!1;if(this._waitForTotalLength){this._waitForTotalLength=!1,this._totalLengthReceived=!0,t=!0;var n=e.total;this._internalAbort(),null!=n&0!==n&&(this._totalLength=n)}if(-1===this._range.to?this._contentLength=this._totalLength-this._range.from:this._contentLength=this._range.to-this._range.from+1,t)return void this._openSubRange();this._onContentLengthKnown&&this._onContentLengthKnown(this._contentLength)}var i=e.loaded-this._lastTimeLoaded;this._lastTimeLoaded=e.loaded,this._speedSampler.addBytes(i)}}},{key:"_normalizeSpeed",value:function(e){var t=this._chunkSizeKBList,n=t.length-1,i=0,r=0,s=n;if(e=t[i]&&e=3&&(t=this._speedSampler.currentKBps),0!==t){var n=this._normalizeSpeed(t);this._currentSpeedNormalized!==n&&(this._currentSpeedNormalized=n,this._currentChunkSizeKB=n)}var i=e.target.response,r=this._range.from+this._receivedLength;this._receivedLength+=i.byteLength;var s=!1;null!=this._contentLength&&this._receivedLength0&&this._receivedLength0&&(this._requestSetTime=!0,this._mediaElement.currentTime=0),this._transmuxer=new p.default(this._mediaDataSource,this._config),this._transmuxer.on(g.default.INIT_SEGMENT,function(t,n){e._msectl.appendInitSegment(n)}),this._transmuxer.on(g.default.MEDIA_SEGMENT,function(t,n){if(e._msectl.appendMediaSegment(n),e._config.lazyLoad&&!e._config.isLive){var i=e._mediaElement.currentTime;n.info.endDts>=1e3*(i+e._config.lazyLoadMaxDuration)&&null==e._progressChecker&&(d.default.v(e.TAG,"Maximum buffering duration exceeded, suspend transmuxing task"),e._suspendTransmuxer())}}),this._transmuxer.on(g.default.LOADING_COMPLETE,function(){e._msectl.endOfStream(),e._emitter.emit(_.default.LOADING_COMPLETE)}),this._transmuxer.on(g.default.RECOVERED_EARLY_EOF,function(){e._emitter.emit(_.default.RECOVERED_EARLY_EOF)}),this._transmuxer.on(g.default.IO_ERROR,function(t,n){e._emitter.emit(_.default.ERROR,k.ErrorTypes.NETWORK_ERROR,t,n)}),this._transmuxer.on(g.default.DEMUX_ERROR,function(t,n){e._emitter.emit(_.default.ERROR,k.ErrorTypes.MEDIA_ERROR,t,{code:-1,msg:n})}), +this._transmuxer.on(g.default.MEDIA_INFO,function(t){e._mediaInfo=t,e._emitter.emit(_.default.MEDIA_INFO,Object.assign({},t))}),this._transmuxer.on(g.default.STATISTICS_INFO,function(t){e._statisticsInfo=e._fillStatisticsInfo(t),e._emitter.emit(_.default.STATISTICS_INFO,Object.assign({},e._statisticsInfo))}),this._transmuxer.on(g.default.RECOMMEND_SEEKPOINT,function(t){e._mediaElement&&!e._config.accurateSeek&&(e._requestSetTime=!0,e._mediaElement.currentTime=t/1e3)}),this._transmuxer.open()}}},{key:"unload",value:function(){this._mediaElement&&this._mediaElement.pause(),this._msectl&&this._msectl.seek(0),this._transmuxer&&(this._transmuxer.close(),this._transmuxer.destroy(),this._transmuxer=null)}},{key:"play",value:function(){return this._mediaElement.play()}},{key:"pause",value:function(){this._mediaElement.pause()}},{key:"_fillStatisticsInfo",value:function(e){if(e.playerType=this._type,!(this._mediaElement instanceof HTMLVideoElement))return e;var t=!0,n=0,i=0;if(this._mediaElement.getVideoPlaybackQuality){var r=this._mediaElement.getVideoPlaybackQuality();n=r.totalVideoFrames,i=r.droppedVideoFrames}else void 0!=this._mediaElement.webkitDecodedFrameCount?(n=this._mediaElement.webkitDecodedFrameCount,i=this._mediaElement.webkitDroppedFrameCount):t=!1;return t&&(e.decodedFrames=n,e.droppedFrames=i),e}},{key:"_onmseUpdateEnd",value:function(){if(this._config.lazyLoad&&!this._config.isLive){for(var e=this._mediaElement.buffered,t=this._mediaElement.currentTime,n=0,i=0;i=t+this._config.lazyLoadMaxDuration&&null==this._progressChecker&&(d.default.v(this.TAG,"Maximum buffering duration exceeded, suspend transmuxing task"),this._suspendTransmuxer())}}},{key:"_onmseBufferFull",value:function(){d.default.v(this.TAG,"MSE SourceBuffer is full, suspend transmuxing task"),null==this._progressChecker&&this._suspendTransmuxer()}},{key:"_suspendTransmuxer",value:function(){this._transmuxer&&(this._transmuxer.pause(),null==this._progressChecker&&(this._progressChecker=window.setInterval(this._checkProgressAndResume.bind(this),1e3)))}},{key:"_checkProgressAndResume",value:function(){for(var e=this._mediaElement.currentTime,t=this._mediaElement.buffered,n=!1,i=0;i=r&&e=s-this._config.lazyLoadRecoverDuration&&(n=!0);break}}n&&(window.clearInterval(this._progressChecker),this._progressChecker=null,n&&(d.default.v(this.TAG,"Continue loading from paused position"),this._transmuxer.resume()))}},{key:"_isTimepointBuffered",value:function(e){for(var t=this._mediaElement.buffered,n=0;n=i&&e0){var r=this._mediaElement.buffered.start(0);(r<1&&e0&&t.currentTime0){var i=n.start(0);if(i<1&&t0&&(this._mediaElement.currentTime=0),this._mediaElement.preload="auto",this._mediaElement.load(),this._statisticsReporter=window.setInterval(this._reportStatisticsInfo.bind(this),this._config.statisticsInfoReportInterval)}},{key:"unload",value:function(){this._mediaElement&&(this._mediaElement.src="",this._mediaElement.removeAttribute("src")),null!=this._statisticsReporter&&(window.clearInterval(this._statisticsReporter),this._statisticsReporter=null)}},{key:"play",value:function(){return this._mediaElement.play()}},{key:"pause",value:function(){this._mediaElement.pause()}},{key:"_onvLoadedMetadata",value:function(e){null!=this._pendingSeekTime&&(this._mediaElement.currentTime=this._pendingSeekTime,this._pendingSeekTime=null),this._emitter.emit(d.default.MEDIA_INFO,this.mediaInfo)}},{key:"_reportStatisticsInfo",value:function(){this._emitter.emit(d.default.STATISTICS_INFO,this.statisticsInfo)}},{key:"type",get:function(){return this._type}},{key:"buffered",get:function(){return this._mediaElement.buffered}},{key:"duration",get:function(){return this._mediaElement.duration}},{key:"volume",get:function(){return this._mediaElement.volume},set:function(e){this._mediaElement.volume=e}},{key:"muted",get:function(){return this._mediaElement.muted},set:function(e){this._mediaElement.muted=e}},{key:"currentTime",get:function(){return this._mediaElement?this._mediaElement.currentTime:0},set:function(e){this._mediaElement?this._mediaElement.currentTime=e:this._pendingSeekTime=e}},{key:"mediaInfo",get:function(){var e=this._mediaElement instanceof HTMLAudioElement?"audio/":"video/",t={mimeType:e+this._mediaDataSource.type};return this._mediaElement&&(t.duration=Math.floor(1e3*this._mediaElement.duration),this._mediaElement instanceof HTMLVideoElement&&(t.width=this._mediaElement.videoWidth,t.height=this._mediaElement.videoHeight)),t}},{key:"statisticsInfo",get:function(){var e={playerType:this._type,url:this._mediaDataSource.url};if(!(this._mediaElement instanceof HTMLVideoElement))return e;var t=!0,n=0,i=0;if(this._mediaElement.getVideoPlaybackQuality){var r=this._mediaElement.getVideoPlaybackQuality();n=r.totalVideoFrames,i=r.droppedVideoFrames}else void 0!=this._mediaElement.webkitDecodedFrameCount?(n=this._mediaElement.webkitDecodedFrameCount,i=this._mediaElement.webkitDroppedFrameCount):t=!1;return t&&(e.decodedFrames=n,e.droppedFrames=i),e}}]),e}();n.default=c},{"../config.js":5,"../utils/exception.js":40,"./player-events.js":35,events:2}],34:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.ErrorDetails=n.ErrorTypes=void 0;var i=e("../io/loader.js"),r=e("../demux/demux-errors.js"),s=function(e){return e&&e.__esModule?e:{default:e}}(r);n.ErrorTypes={NETWORK_ERROR:"NetworkError",MEDIA_ERROR:"MediaError",OTHER_ERROR:"OtherError"},n.ErrorDetails={NETWORK_EXCEPTION:i.LoaderErrors.EXCEPTION,NETWORK_STATUS_CODE_INVALID:i.LoaderErrors.HTTP_STATUS_CODE_INVALID,NETWORK_TIMEOUT:i.LoaderErrors.CONNECTING_TIMEOUT,NETWORK_UNRECOVERABLE_EARLY_EOF:i.LoaderErrors.UNRECOVERABLE_EARLY_EOF,MEDIA_MSE_ERROR:"MediaMSEError",MEDIA_FORMAT_ERROR:s.default.FORMAT_ERROR,MEDIA_FORMAT_UNSUPPORTED:s.default.FORMAT_UNSUPPORTED,MEDIA_CODEC_UNSUPPORTED:s.default.CODEC_UNSUPPORTED}},{"../demux/demux-errors.js":16,"../io/loader.js":24}],35:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i={ERROR:"error",LOADING_COMPLETE:"loading_complete",RECOVERED_EARLY_EOF:"recovered_early_eof",MEDIA_INFO:"media_info",STATISTICS_INFO:"statistics_info"};n.default=i},{}],36:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n>>24&255,n[1]=t>>>16&255,n[2]=t>>>8&255,n[3]=255&t,n.set(e,4);for(var a=8,o=0;o>>24&255,t>>>16&255,t>>>8&255,255&t,n>>>24&255,n>>>16&255,n>>>8&255,255&n,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]))}},{key:"trak",value:function(t){return e.box(e.types.trak,e.tkhd(t),e.mdia(t))}},{key:"tkhd",value:function(t){var n=t.id,i=t.duration,r=t.presentWidth,s=t.presentHeight;return e.box(e.types.tkhd,new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,0,0,0,0,i>>>24&255,i>>>16&255,i>>>8&255,255&i,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,r>>>8&255,255&r,0,0,s>>>8&255,255&s,0,0]))}},{key:"mdia",value:function(t){return e.box(e.types.mdia,e.mdhd(t),e.hdlr(t),e.minf(t))}},{key:"mdhd",value:function(t){var n=t.timescale,i=t.duration;return e.box(e.types.mdhd,new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,i>>>24&255,i>>>16&255,i>>>8&255,255&i,85,196,0,0]))}},{key:"hdlr",value:function(t){var n=null;return n="audio"===t.type?e.constants.HDLR_AUDIO:e.constants.HDLR_VIDEO,e.box(e.types.hdlr,n)}},{key:"minf",value:function(t){var n=null;return n="audio"===t.type?e.box(e.types.smhd,e.constants.SMHD):e.box(e.types.vmhd,e.constants.VMHD),e.box(e.types.minf,n,e.dinf(),e.stbl(t))}},{key:"dinf",value:function(){return e.box(e.types.dinf,e.box(e.types.dref,e.constants.DREF))}},{key:"stbl",value:function(t){return e.box(e.types.stbl,e.stsd(t),e.box(e.types.stts,e.constants.STTS),e.box(e.types.stsc,e.constants.STSC),e.box(e.types.stsz,e.constants.STSZ),e.box(e.types.stco,e.constants.STCO))}},{key:"stsd",value:function(t){return"audio"===t.type?"mp3"===t.codec?e.box(e.types.stsd,e.constants.STSD_PREFIX,e.mp3(t)):e.box(e.types.stsd,e.constants.STSD_PREFIX,e.mp4a(t)):e.box(e.types.stsd,e.constants.STSD_PREFIX,e.avc1(t))}},{key:"mp3",value:function(t){var n=t.channelCount,i=t.audioSampleRate,r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,n,0,16,0,0,0,0,i>>>8&255,255&i,0,0]);return e.box(e.types[".mp3"],r)}},{key:"mp4a",value:function(t){var n=t.channelCount,i=t.audioSampleRate,r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,n,0,16,0,0,0,0,i>>>8&255,255&i,0,0]);return e.box(e.types.mp4a,r,e.esds(t))}},{key:"esds",value:function(t){var n=t.config||[],i=n.length,r=new Uint8Array([0,0,0,0,3,23+i,0,1,0,4,15+i,64,21,0,0,0,0,0,0,0,0,0,0,0,5].concat([i]).concat(n).concat([6,1,2]));return e.box(e.types.esds,r)}},{key:"avc1",value:function(t){var n=t.avcc,i=t.codecWidth,r=t.codecHeight,s=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i>>>8&255,255&i,r>>>8&255,255&r,0,72,0,0,0,72,0,0,0,0,0,0,0,1,10,120,113,113,47,102,108,118,46,106,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,255,255]);return e.box(e.types.avc1,s,e.box(e.types.avcC,n))}},{key:"mvex",value:function(t){return e.box(e.types.mvex,e.trex(t))}},{key:"trex",value:function(t){var n=t.id,i=new Uint8Array([0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return e.box(e.types.trex,i)}},{key:"moof",value:function(t,n){return e.box(e.types.moof,e.mfhd(t.sequenceNumber),e.traf(t,n))}},{key:"mfhd",value:function(t){var n=new Uint8Array([0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,255&t]);return e.box(e.types.mfhd,n)}},{key:"traf",value:function(t,n){var i=t.id,r=e.box(e.types.tfhd,new Uint8Array([0,0,0,0,i>>>24&255,i>>>16&255,i>>>8&255,255&i])),s=e.box(e.types.tfdt,new Uint8Array([0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n])),a=e.sdtp(t),o=e.trun(t,a.byteLength+16+16+8+16+8+8);return e.box(e.types.traf,r,s,o,a)}},{key:"sdtp",value:function(t){for(var n=t.samples||[],i=n.length,r=new Uint8Array(4+i),s=0;s>>24&255,r>>>16&255,r>>>8&255,255&r,n>>>24&255,n>>>16&255,n>>>8&255,255&n],0);for(var o=0;o>>24&255,u>>>16&255,u>>>8&255,255&u,l>>>24&255,l>>>16&255,l>>>8&255,255&l,d.isLeading<<2|d.dependsOn,d.isDependedOn<<6|d.hasRedundancy<<4|d.isNonSync,0,0,h>>>24&255,h>>>16&255,h>>>8&255,255&h],12+16*o)}return e.box(e.types.trun,a)}},{key:"mdat",value:function(t){return e.box(e.types.mdat,t)}}]),e}();s.init(),n.default=s},{}],38:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n=1?A[A.length-1].duration:Math.floor(a);var D=!1,B=null;if(M>1.5*a&&"mp3"!==this._audioMeta.codec&&this._fillAudioTimestampGap&&!c.default.safari){D=!0;var j=Math.abs(M-a),P=Math.ceil(j/a),U=x+a;o.default.w(this.TAG,"Large audio timestamp gap detected, may cause AV sync to drift. Silent frames will be generated to avoid unsync.\ndts: "+(x+M)+" ms, expected: "+(x+Math.round(a))+" ms, delta: "+Math.round(j)+" ms, generate: "+P+" frames");var N=h.default.getSilentFrame(this._audioMeta.originalCodec,this._audioMeta.channelCount);null==N&&(o.default.w(this.TAG,"Unable to generate silent frame for "+this._audioMeta.originalCodec+" with "+this._audioMeta.channelCount+" channels, repeat last frame"),N=C),B=[];for(var F=0;F0){var V=B[B.length-1];V.duration=G-V.dts}var z={dts:G,pts:G,cts:0,unit:N,size:N.byteLength,duration:0,originalDts:I,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0}};B.push(z),v+=C.byteLength,U+=a}var H=B[B.length-1];H.duration=x+M-H.dts,M=Math.round(a)}A.push({dts:x,pts:x,cts:0,unit:T.unit,size:T.unit.byteLength,duration:M,originalDts:I,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0}}),D&&A.push.apply(A,B)}u?p=new Uint8Array(v):(p=new Uint8Array(v),p[0]=v>>>24&255,p[1]=v>>>16&255,p[2]=v>>>8&255,p[3]=255&v,p.set(l.default.types.mdat,4));for(var K=0;K>>24&255,h[1]=d>>>16&255,h[2]=d>>>8&255,h[3]=255&d,h.set(l.default.types.mdat,4);var f=n[0].dts-this._dtsBase;if(this._videoNextDts)i=f-this._videoNextDts;else if(this._videoSegmentInfoList.isEmpty())i=0;else{var c=this._videoSegmentInfoList.getLastSampleBefore(f);if(null!=c){var m=f-(c.originalDts+c.duration);m<=3&&(m=0);var p=c.dts+c.duration+m;i=f-p}else i=0}for(var v=new _.MediaSegmentInfo,g=[],y=0;y=1?g[g.length-1].duration:Math.floor(this._videoMeta.refSampleDuration);if(S){var A=new _.SampleInfo(k,w,R,E.dts,!0);A.fileposition=E.fileposition,v.appendSyncPoint(A)}g.push({dts:k,pts:w,cts:L,units:E.units,size:E.length,isKeyframe:S,duration:R,originalDts:b,flags:{isLeading:0,dependsOn:S?2:1,isDependedOn:S?1:0,hasRedundancy:0,isNonSync:S?0:1}})}for(var O=0;O=0&&/(rv)(?::| )([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(firefox)[ \/]([\w.]+)/.exec(e)||[],n=/(ipad)/.exec(e)||/(ipod)/.exec(e)||/(windows phone)/.exec(e)||/(iphone)/.exec(e)||/(kindle)/.exec(e)||/(android)/.exec(e)||/(windows)/.exec(e)||/(mac)/.exec(e)||/(linux)/.exec(e)||/(cros)/.exec(e)||[],r={browser:t[5]||t[3]||t[1]||"",version:t[2]||t[4]||"0",majorVersion:t[4]||t[2]||"0",platform:n[0]||""},s={};if(r.browser){s[r.browser]=!0;var a=r.majorVersion.split(".");s.version={major:parseInt(r.majorVersion,10),string:r.version},a.length>1&&(s.version.minor=parseInt(a[1],10)),a.length>2&&(s.version.build=parseInt(a[2],10))}r.platform&&(s[r.platform]=!0), +(s.chrome||s.opr||s.safari)&&(s.webkit=!0),(s.rv||s.iemobile)&&(s.rv&&delete s.rv,r.browser="msie",s.msie=!0),s.edge&&(delete s.edge,r.browser="msedge",s.msedge=!0),s.opr&&(r.browser="opera",s.opera=!0),s.safari&&s.android&&(r.browser="android",s.android=!0),s.name=r.browser,s.platform=r.platform;for(var o in i)i.hasOwnProperty(o)&&delete i[o];Object.assign(i,s)}(),n.default=i},{}],40:[function(e,t,n){"use strict";function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function r(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","error",i),e.ENABLE_ERROR&&(console.error?console.error(i):console.warn?console.warn(i):console.log(i))}},{key:"i",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","info",i),e.ENABLE_INFO&&(console.info?console.info(i):console.log(i))}},{key:"w",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","warn",i),e.ENABLE_WARN&&(console.warn?console.warn(i):console.log(i))}},{key:"d",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","debug",i),e.ENABLE_DEBUG&&(console.debug?console.debug(i):console.log(i))}},{key:"v",value:function(t,n){t&&!e.FORCE_GLOBAL_TAG||(t=e.GLOBAL_TAG);var i="["+t+"] > "+n;e.ENABLE_CALLBACK&&e.emitter.emit("log","verbose",i),e.ENABLE_VERBOSE&&console.log(i)}}]),e}();o.GLOBAL_TAG="flv.js",o.FORCE_GLOBAL_TAG=!1,o.ENABLE_ERROR=!0,o.ENABLE_INFO=!0,o.ENABLE_WARN=!0,o.ENABLE_DEBUG=!0,o.ENABLE_VERBOSE=!0,o.ENABLE_CALLBACK=!1,o.emitter=new a.default,n.default=o},{events:2}],42:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0){var n=e.getConfig();t.emit("change",n)}}},{key:"registerListener",value:function(t){e.emitter.addListener("change",t)}},{key:"removeListener",value:function(t){e.emitter.removeListener("change",t)}},{key:"addLogListener",value:function(t){l.default.emitter.addListener("log",t),l.default.emitter.listenerCount("log")>0&&(l.default.ENABLE_CALLBACK=!0,e._notifyChange())}},{key:"removeLogListener",value:function(t){l.default.emitter.removeListener("log",t),0===l.default.emitter.listenerCount("log")&&(l.default.ENABLE_CALLBACK=!1,e._notifyChange())}},{key:"forceGlobalTag",get:function(){return l.default.FORCE_GLOBAL_TAG},set:function(t){l.default.FORCE_GLOBAL_TAG=t,e._notifyChange()}},{key:"globalTag",get:function(){return l.default.GLOBAL_TAG},set:function(t){l.default.GLOBAL_TAG=t,e._notifyChange()}},{key:"enableAll",get:function(){return l.default.ENABLE_VERBOSE&&l.default.ENABLE_DEBUG&&l.default.ENABLE_INFO&&l.default.ENABLE_WARN&&l.default.ENABLE_ERROR},set:function(t){l.default.ENABLE_VERBOSE=t,l.default.ENABLE_DEBUG=t,l.default.ENABLE_INFO=t,l.default.ENABLE_WARN=t,l.default.ENABLE_ERROR=t,e._notifyChange()}},{key:"enableDebug",get:function(){return l.default.ENABLE_DEBUG},set:function(t){l.default.ENABLE_DEBUG=t,e._notifyChange()}},{key:"enableVerbose",get:function(){return l.default.ENABLE_VERBOSE},set:function(t){l.default.ENABLE_VERBOSE=t,e._notifyChange()}},{key:"enableInfo",get:function(){return l.default.ENABLE_INFO},set:function(t){l.default.ENABLE_INFO=t,e._notifyChange()}},{key:"enableWarn",get:function(){return l.default.ENABLE_WARN},set:function(t){l.default.ENABLE_WARN=t,e._notifyChange()}},{key:"enableError",get:function(){return l.default.ENABLE_ERROR},set:function(t){l.default.ENABLE_ERROR=t,e._notifyChange()}}]),e}();d.emitter=new o.default,n.default=d},{"./logger.js":41,events:2}],43:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=128){t.push(String.fromCharCode(65535&a)),r+=2;continue}}}else if(n[r]<240){if(i(n,r,2)){var o=(15&n[r])<<12|(63&n[r+1])<<6|63&n[r+2];if(o>=2048&&55296!=(63488&o)){t.push(String.fromCharCode(65535&o)),r+=3;continue}}}else if(n[r]<248&&i(n,r,3)){var u=(7&n[r])<<18|(63&n[r+1])<<12|(63&n[r+2])<<6|63&n[r+3];if(u>65536&&u<1114112){u-=65536,t.push(String.fromCharCode(u>>>10|55296)),t.push(String.fromCharCode(1023&u|56320)),r+=4;continue}}t.push(String.fromCharCode(65533)),++r}return t.join("")}Object.defineProperty(n,"__esModule",{value:!0}),n.default=r},{}]},{},[21])(21)}); +//# sourceMappingURL=flv.min.js.map diff --git a/tools/MP4 Stream/flv.min.js.map b/tools/MP4 Stream/flv.min.js.map new file mode 100644 index 0000000..05e110e --- /dev/null +++ b/tools/MP4 Stream/flv.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/es6-promise/dist/es6-promise.js","node_modules/events/events.js","node_modules/process/browser.js","node_modules/webworkify/index.js","src/config.js","src/core/features.js","src/core/media-info.js","src/core/media-segment-info.js","src/core/mse-controller.js","src/core/mse-events.js","src/core/transmuxer.js","src/core/transmuxing-controller.js","src/core/transmuxing-events.js","src/core/transmuxing-worker.js","src/demux/amf-parser.js","src/demux/demux-errors.js","src/demux/exp-golomb.js","src/demux/flv-demuxer.js","src/demux/sps-parser.js","src/flv.js","src/index.js","src/io/fetch-stream-loader.js","src/io/io-controller.js","src/io/loader.js","src/io/param-seek-handler.js","src/io/range-seek-handler.js","src/io/speed-sampler.js","src/io/websocket-loader.js","src/io/xhr-moz-chunked-loader.js","src/io/xhr-msstream-loader.js","src/io/xhr-range-loader.js","src/player/flv-player.js","src/player/native-player.js","src/player/player-errors.js","src/player/player-events.js","src/remux/aac-silent.js","src/remux/mp4-generator.js","src/remux/mp4-remuxer.js","src/utils/browser.js","src/utils/exception.js","src/utils/logger.js","src/utils/logging-control.js","src/utils/polyfill.js","src/utils/utf8-conv.js"],"names":["f","exports","module","define","amd","g","window","global","self","this","flvjs","e","t","n","r","s","o","u","a","require","i","Error","code","l","call","length","1","_dereq_","factory","ES6Promise","objectOrFunction","x","isFunction","setScheduler","scheduleFn","customSchedulerFn","setAsap","asapFn","asap","useVertxTimer","vertxNext","flush","useSetTimeout","globalSetTimeout","setTimeout","len","callback","queue","undefined","then","onFulfillment","onRejection","_arguments","arguments","parent","child","constructor","noop","PROMISE_ID","makePromise","_state","invokeCallback","_result","subscribe","resolve","object","Constructor","promise","_resolve","selfFulfillment","TypeError","cannotReturnOwn","getThen","error","GET_THEN_ERROR","tryThen","value","fulfillmentHandler","rejectionHandler","handleForeignThenable","thenable","sealed","fulfill","reason","_reject","_label","handleOwnThenable","FULFILLED","REJECTED","handleMaybeThenable","maybeThenable","then$$","publishRejection","_onerror","publish","PENDING","_subscribers","subscribers","settled","detail","ErrorObject","tryCatch","TRY_CATCH_ERROR","hasCallback","succeeded","failed","initializePromise","resolver","nextId","id","Enumerator","input","_instanceConstructor","isArray","_input","_remaining","Array","_enumerate","validationError","all","entries","race","reject","_","needsResolver","needsNew","Promise","polyfill","local","Function","P","promiseToString","Object","prototype","toString","cast","_isArray","arg","scheduleFlush","browserWindow","browserGlobal","BrowserMutationObserver","MutationObserver","WebKitMutationObserver","isNode","process","isWorker","Uint8ClampedArray","importScripts","MessageChannel","nextTick","iterations","observer","node","document","createTextNode","observe","characterData","data","channel","port1","onmessage","port2","postMessage","vertx","runOnLoop","runOnContext","Math","random","substring","_eachEntry","entry","c","resolve$$","_then","_settledAt","_willSettleAt","state","enumerator","_setScheduler","_setAsap","_asap","catch","EventEmitter","_events","_maxListeners","isNumber","isObject","isUndefined","defaultMaxListeners","setMaxListeners","isNaN","emit","type","er","handler","args","listeners","err","context","slice","apply","addListener","listener","m","newListener","push","warned","console","trace","on","once","removeListener","fired","list","position","splice","removeAllListeners","key","listenerCount","evlistener","emitter","defaultSetTimout","defaultClearTimeout","runTimeout","fun","cachedSetTimeout","runClearTimeout","marker","cachedClearTimeout","clearTimeout","cleanUpNextTick","draining","currentQueue","concat","queueIndex","drainQueue","timeout","run","Item","array","title","browser","env","argv","version","versions","off","prependListener","prependOnceListener","name","binding","cwd","chdir","dir","umask","bundleFn","sources","cache","stringify","JSON","fn","options","resolveSources","workerSources","depPath","depKey","wkey","cacheKeys","keys","exp","default","floor","pow","wcache","skey","scache","src","map","join","URL","webkitURL","mozURL","msURL","blob","Blob","bare","workerUrl","createObjectURL","worker","Worker","objectURL","createDefaultConfig","assign","defaultConfig","enableWorker","enableStashBuffer","stashInitialSize","isLive","lazyLoad","lazyLoadMaxDuration","lazyLoadRecoverDuration","deferLoadAfterSourceOpen","autoCleanupMaxBackwardDuration","autoCleanupMinBackwardDuration","statisticsInfoReportInterval","fixAudioTimestampGap","accurateSeek","seekType","seekParamStart","seekParamEnd","rangeLoadZeroStart","customSeekHandler","reuseRedirectedURL","_ioController","_config","Features","MediaSource","isTypeSupported","ioctl","_ioController2","loaderType","destroy","mimeType","videoElement","createElement","canPlay","canPlayType","features","mseFlvPlayback","mseLiveFlvPlayback","networkStreamIO","networkLoaderName","nativeMP4H264Playback","nativeWebmVP8Playback","nativeWebmVP9Playback","supportMSEH264Playback","supportNetworkStreamIO","getNetworkLoaderTypeName","supportNativeMediaPlayback","MediaInfo","_classCallCheck","duration","hasAudio","hasVideo","audioCodec","videoCodec","audioDataRate","videoDataRate","audioSampleRate","audioChannelCount","width","height","fps","profile","level","chromaFormat","sarNum","sarDen","metadata","segments","segmentCount","hasKeyframesIndex","keyframesIndex","audioInfoComplete","videoInfoComplete","milliseconds","table","keyframeIdx","_search","times","index","fileposition","filepositions","idx","last","mid","lbound","ubound","SampleInfo","dts","pts","originalDts","isSync","isSyncPoint","MediaSegmentInfo","beginDts","endDts","beginPts","endPts","originalBeginDts","originalEndDts","syncPoints","firstSample","lastSample","sampleInfo","IDRSampleList","_list","clear","MediaSegmentInfoList","_type","_lastAppendLocation","_searchNearestSegmentBefore","mediaSegmentInfo","msi","lastAppendIdx","insertIdx","segment","getLastSegmentBefore","segmentIdx","_logger","_browser","_mseEvents","_mediaSegmentInfo","_exception","MSEController","config","TAG","_emitter","_events2","autoCleanupSourceBuffer","onSourceOpen","_onSourceOpen","bind","onSourceEnded","_onSourceEnded","onSourceClose","_onSourceClose","onSourceBufferError","_onSourceBufferError","onSourceBufferUpdateEnd","_onSourceBufferUpdateEnd","_mediaSource","_mediaSourceObjectURL","_mediaElement","_isBufferFull","_hasPendingEos","_requireSetMediaDuration","_pendingMediaDuration","_pendingSourceBufferInit","_mimeTypes","video","audio","_sourceBuffers","_lastInitSegments","_pendingSegments","_pendingRemoveRanges","_idrList","detachMediaElement","event","mediaElement","IllegalStateException","ms","addEventListener","ps","sb","readyState","removeSourceBuffer","removeEventListener","endOfStream","_logger2","message","removeAttribute","revokeObjectURL","initSegment","deferred","is","container","codec","firstInitSegment","v","addSourceBuffer","_mseEvents2","ERROR","msg","updating","_doAppendSegments","_browser2","safari","mediaDuration","_updateMediaSourceDuration","mediaSegment","_needCleanupSourceBuffer","_doCleanupSourceBuffer","_hasPendingRemoveRanges","seconds","abort","buffered","start","end","_doRemoveRanges","lastInitSegment","_hasPendingSegments","getLastSyncPointBeforeDts","currentTime","doRemove","removeEnd","current","target","ranges","range","shift","remove","pendingSegments","timestampOffset","currentOffset","targetOffset","delta","abs","byteLength","appendBuffer","hasOwnProperty","appendArray","info","unshift","BUFFER_FULL","pendings","appendInitSegment","SOURCE_OPEN","prr","UPDATE_END","MSEEvents","_loggingControl","_transmuxingController","_transmuxingEvents","_transmuxingWorker","_mediaInfo","Transmuxer","mediaDataSource","work","_worker","_transmuxingWorker2","_workerDestroying","_onWorkerMessage","cmd","param","onLoggingConfigChanged","_onLoggingConfigChanged","_loggingControl2","registerListener","getConfig","_controller","_transmuxingController2","ctl","_transmuxingEvents2","IO_ERROR","_onIOError","DEMUX_ERROR","_onDemuxError","INIT_SEGMENT","_onInitSegment","MEDIA_SEGMENT","_onMediaSegment","LOADING_COMPLETE","_onLoadingComplete","RECOVERED_EARLY_EOF","_onRecoveredEarlyEof","MEDIA_INFO","_onMediaInfo","STATISTICS_INFO","_onStatisticsInfo","RECOMMEND_SEEKPOINT","_onRecommendSeekpoint","stop","seek","pause","resume","_this","_this2","_this3","_this4","mediaInfo","_this5","statisticsInfo","_this6","_this7","_this8","_this9","terminate","setPrototypeOf","_mediaInfo2","logcat","_flvDemuxer","_mp4Remuxer","_demuxErrors","TransmuxingController","filesize","url","cors","withCredentials","_mediaDataSource","_currentSegmentIndex","totalDuration","forEach","timestampBase","referrerPolicy","_demuxer","_remuxer","_ioctl","_pendingSeekTime","_pendingResolveSeekPoint","_statisticsReporter","_disableStatisticsReporter","_loadSegment","_enableStatisticsReporter","segmentIndex","optionalFrom","dataSource","onError","_onIOException","onSeeked","_onIOSeeked","onComplete","_onIOComplete","onRedirect","_onIORedirect","onRecoveredEarlyEof","_onIORecoveredEarlyEof","bindDataSource","onDataArrival","_onInitChunkArrival","open","_internalAbort","isWorking","isPaused","isSeekable","targetSegmentIndex","_searchSegmentIndexContains","segmentInfo","keyframe","getNearestKeyframe","targetSegmentInfo","insertDiscontinuity","_keyframe","resetMediaInfo","_reportSegmentMediaInfo","byteStart","probeData","consumed","parseChunks","_flvDemuxer2","probe","match","_mp4Remuxer2","mds","overridedDuration","overridedHasAudio","overridedHasVideo","_onDemuxException","onMediaInfo","onInitSegment","_onRemuxerInitSegmentArrival","onMediaSegment","_onRemuxerMediaSegmentArrival","_demuxErrors2","FORMAT_UNSUPPORTED","extraData","nextSegmentIndex","redirectedURL","seekpoint","setInterval","_reportStatisticsInfo","clearInterval","exportInfo","currentURL","hasRedirect","currentRedirectedURL","speed","currentSpeed","currentSegmentIndex","totalSegmentCount","TransmuxingEvents","_polyfill","TransmuxingWorker","obj","onLoadingComplete","onStatisticsInfo","statInfo","onIOError","onDemuxError","onRecommendSeekpoint","onLogcatCallback","str","controller","logcatListener","_polyfill2","install","applyConfig","enableCallback","addLogListener","removeLogListener","_utf8Conv","le","buf","ArrayBuffer","DataView","setInt16","Int16Array","AMF","arrayBuffer","dataOffset","dataSize","parseValue","size","parseString","isObjectEnd","objectEnd","parseObject","getUint16","_utf8Conv2","Uint8Array","getUint32","timestamp","getFloat64","getInt16","Date","offset","getUint8","amfstr","terminal","amfobj","_terminal","amfvar","parseVariable","strictArrayLength","val","date","parseDate","amfLongStr","w","DemuxErrors","OK","FORMAT_ERROR","CODEC_UNSUPPORTED","ExpGolomb","uint8array","_buffer","_buffer_index","_total_bytes","_total_bits","_current_word","_current_word_bits_left","buffer_bytes_left","bytes_read","min","word","set","subarray","buffer","bits","InvalidArgumentException","result","bits_need_left","_fillCurrentWord","bits_read_next","result2","readBits","zero_count","_skipLeadingZero","leading_zeros","readUEG","ReadBig32","_amfParser","_spsParser","FLVDemuxer","_onError","_onTrackMetadata","_onDataAvailable","_dataOffset","_firstParse","_dispatch","_hasAudio","hasAudioTrack","_hasVideo","hasVideoTrack","_hasAudioFlagOverrided","_hasVideoFlagOverrided","_audioInitialMetadataDispatched","_videoInitialMetadataDispatched","_metadata","_audioMetadata","_videoMetadata","_naluLengthSize","_timestampBase","_timescale","_duration","_durationOverrided","_referenceFrameRate","fixed","fps_num","fps_den","_flvSoundRateTable","_mpegSamplingRates","_mpegAudioV10SampleRateTable","_mpegAudioV20SampleRateTable","_mpegAudioV25SampleRateTable","_mpegAudioL1BitRateTable","_mpegAudioL2BitRateTable","_mpegAudioL3BitRateTable","_videoTrack","sequenceNumber","samples","_audioTrack","_littleEndian","loader","chunk","_v","tagType","ts2","ts1","ts0","ts3","_parseAudioData","_parseVideoData","_parseScriptData","prevTagSize","_isInitialMetadataDispatched","scriptData","_amfParser2","parseScriptData","onMetaData","_typeof","audiodatarate","videodatarate","framerate","keyframes","_parseKeyframesIndex","isComplete","time","tagTimestamp","soundSpec","soundFormat","soundRate","soundRateIndex","soundType","meta","track","timescale","channelCount","aacData","_parseAACAudioData","packetType","misc","samplingRate","originalCodec","refSampleDuration","mi","aacSample","unit","_misc","_parseMP3AudioData","_mi","bitRate","_dts","mp3Sample","_parseAACAudioSpecificConfig","audioObjectType","originalAudioObjectType","samplingIndex","extensionSamplingIndex","samplingFrequence","channelConfig","userAgent","navigator","toLowerCase","indexOf","requestHeader","ver","layer","bitrate_index","sampling_freq_index","channel_mode","channel_count","sample_rate","bit_rate","tagPosition","spec","frameType","codecId","_parseAVCVideoPacket","cts","_parseAVCDecoderConfigurationRecord","_parseAVCVideoData","avcc","avcProfile","spsCount","sps","_spsParser2","parseSPS","codecWidth","codec_size","codecHeight","presentWidth","present_size","presentHeight","profile_string","level_string","bitDepth","bit_depth","chroma_format","sarRatio","sar_ratio","frameRate","frame_rate","codecArray","codecString","j","h","chroma_format_string","ppsCount","_i","_len","units","lengthSize","naluSize","unitType","avcSample","isKeyframe","base","mismatch","_expGolomb","SPSParser","src_length","dst","dst_idx","rbsp","_ebsp2rbsp","gb","_expGolomb2","readByte","profile_idc","level_idc","getProfileString","getLevelString","chroma_format_idc","chroma_format_table","readBool","scaling_list_count","_skipScalingList","pic_order_cnt_type","readSEG","num_ref_frames_in_pic_order_cnt_cycle","pic_width_in_mbs_minus1","pic_height_in_map_units_minus1","frame_mbs_only_flag","frame_crop_left_offset","frame_crop_right_offset","frame_crop_top_offset","frame_crop_bottom_offset","sar_width","sar_height","fps_fixed","aspect_ratio_idc","sar_w_table","sar_h_table","num_units_in_tick","time_scale","sarScale","crop_unit_x","crop_unit_y","sub_wc","sub_hc","codec_width","codec_height","present_width","ceil","getChromaFormatString","count","last_scale","next_scale","delta_scale","toFixed","chroma","createPlayer","optionalConfig","_flvPlayer2","_nativePlayer2","isSupported","_features2","getFeatureList","_features","_flvPlayer","_nativePlayer","_playerEvents","_playerErrors","Events","_playerEvents2","ErrorTypes","ErrorDetails","FlvPlayer","NativePlayer","LoggingControl","defineProperty","enumerable","get","_loader","FetchStreamLoader","seekHandler","_possibleConstructorReturn","__proto__","getPrototypeOf","_seekHandler","_needStash","_requestAbort","_contentLength","_receivedLength","isWorkWellEdge","msedge","minor","browserNotBlacklisted","fetch","ReadableStream","_get","_dataSource","_range","sourceURL","seekConfig","headers","Headers","configHeaders","append","params","method","mode","credentials","_status","LoaderStatus","kConnecting","res","kIdle","ok","status","_onURLRedirect","removeURLParameters","lengthHeader","parseInt","_onContentLengthKnown","_pump","body","getReader","kError","RuntimeException","statusText","LoaderErrors","HTTP_STATUS_CODE_INVALID","EXCEPTION","reader","read","done","kComplete","_onComplete","from","cancel","kBuffering","_onDataArrival","EARLY_EOF","_speedSampler","_fetchStreamLoader","_xhrMozChunkedLoader","_xhrMsstreamLoader","_xhrRangeLoader","_websocketLoader","_rangeSeekHandler","_paramSeekHandler","IOController","_extraData","_stashInitialSize","_stashUsed","_stashSize","_bufferSize","_stashBuffer","_stashByteStart","_enableStash","_loaderClass","_isWebSocketURL","test","_refTotalLength","_totalLength","_fullRequestFlag","_currentRange","_redirectedURL","_speedNormalized","_speedSampler2","_speedNormalizeList","_isEarlyEofReconnecting","_paused","_resumeFrom","_onSeeked","_onRedirect","_selectSeekHandler","_selectLoader","_createLoader","_rangeSeekHandler2","paramStart","paramEnd","_paramSeekHandler2","_websocketLoader2","_fetchStreamLoader2","_xhrMozChunkedLoader2","_xhrRangeLoader2","needStashBuffer","onContentLengthKnown","onURLRedirect","_onLoaderChunkArrival","_onLoaderComplete","_onLoaderError","to","reset","bytes","_internalSeek","dropUnconsumed","_flushStashBuffer","requestRange","expectedBytes","bufferNewSize","newBuffer","stashOldArray","normalized","stashSizeKB","bufferSize","_expandBuffer","chunks","contentLength","receivedLength","addBytes","KBps","lastSecondKBps","_normalizeSpeed","_adjustStashSize","_stashArray2","_stashArray3","_consumed2","_dispatchChunks","_remainArray","_consumed3","_remain","remain","stashArray","_stashArray","_consumed","remainArray","UNRECOVERABLE_EARLY_EOF","nextFrom","CONNECTING_TIMEOUT","BaseLoader","typeName","NotImplementedException","ParamSeekHandler","_startName","_endName","baseUrl","needAnd","seekedURL","baseURL","split","queryIndex","resultParams","pairs","pair","requireAnd","RangeSeekHandler","zeroStart","_zeroStart","SpeedSampler","_firstCheckpoint","_lastCheckpoint","_intervalBytes","_totalBytes","_lastSecondBytes","performance","now","_now","durationSeconds","currentKBps","WebSocketLoader","_ws","WebSocket","ws","binaryType","onopen","_onWebSocketOpen","onclose","_onWebSocketClose","_onWebSocketMessage","onerror","_onWebSocketError","close","_dispatchArrayBuffer","FileReader","onload","readAsArrayBuffer","arraybuffer","MozChunkedLoader","_xhr","xhr","XMLHttpRequest","responseType","onreadystatechange","onprogress","onloadend","_requestURL","_onReadyStateChange","_onProgress","_onLoadEnd","_onXhrError","setRequestHeader","send","responseURL","total","response","loaded","MSStreamLoader","_reader","_totalRange","_currentRequestURL","_currentRedirectedURL","_bufferLimit","_lastTimeBufferSize","_isReconnecting","MSStream","MSStreamReader","_internalOpen","isSubrange","_msrOnProgress","_msrOnLoad","_msrOnError","_xhrOnReadyStateChange","_xhrOnError","getResponseHeader","msstream","bigbuffer","_doReconnectIfNeeded","RangeLoader","_chunkSizeKBList","_currentChunkSizeKB","_currentSpeedNormalized","_zeroSpeedChunkCount","_waitForTotalLength","_totalLengthReceived","_currentRequestRange","_lastTimeLoaded","useRefTotalLength","_openSubRange","chunkSize","_onLoad","openNextRange","reportComplete","_transmuxer","_mseController","onvLoadedMetadata","_onvLoadedMetadata","onvSeeking","_onvSeeking","onvCanPlay","_onvCanPlay","onvStalled","_onvStalled","onvProgress","_onvProgress","_requestSetTime","_seekpointRecord","_progressChecker","_msectl","_mseSourceOpened","_hasPendingLoad","_receivedCanPlay","_statisticsInfo","chromeNeedIDRFix","chrome","major","build","_alwaysSeekKeyframe","msie","unload","_mseController2","_onmseUpdateEnd","_onmseBufferFull","load","MEDIA_ERROR","MEDIA_MSE_ERROR","attachMediaElement","_transmuxer2","appendMediaSegment","_suspendTransmuxer","NETWORK_ERROR","_fillStatisticsInfo","play","playerType","HTMLVideoElement","hasQualityInfo","decoded","dropped","getVideoPlaybackQuality","quality","totalVideoFrames","droppedVideoFrames","webkitDecodedFrameCount","webkitDroppedFrameCount","decodedFrames","droppedFrames","currentRangeEnd","_checkProgressAndResume","needResume","directSeek","_isTimepointBuffered","directSeekBegin","directSeekBeginTime","videoBeginTime","idr","recordTime","_checkAndApplyUnbufferedSeekpoint","stalled","media","seekPoint","_checkAndResumeStuckPlayback","volume","muted","preload","mediaPrefix","HTMLAudioElement","videoWidth","videoHeight","OTHER_ERROR","NETWORK_EXCEPTION","NETWORK_STATUS_CODE_INVALID","NETWORK_TIMEOUT","NETWORK_UNRECOVERABLE_EARLY_EOF","MEDIA_FORMAT_ERROR","MEDIA_FORMAT_UNSUPPORTED","MEDIA_CODEC_UNSUPPORTED","PlayerEvents","AAC","MP4","types","avc1","avcC","btrt","dinf","dref","esds","ftyp","hdlr","mdat","mdhd","mdia","mfhd","minf","moof","moov","mp4a","mvex","mvhd","sdtp","stbl","stco","stsc","stsd","stsz","stts","tfdt","tfhd","traf","trak","trun","trex","tkhd","vmhd","smhd",".mp3","charCodeAt","constants","FTYP","STSD_PREFIX","STTS","STSC","STCO","STSZ","HDLR_VIDEO","HDLR_AUDIO","DREF","SMHD","VMHD","datas","arrayCount","box","trackId","xmhd","mp3","sampleRate","configSize","baseMediaDecodeTime","sampleCount","flags","isLeading","dependsOn","isDependedOn","hasRedundancy","isNonSync","init","_mp4Generator","_aacSilent","MP4Remuxer","_isLive","_dtsBase","_dtsBaseInited","_audioDtsBase","Infinity","_videoDtsBase","_audioNextDts","_videoNextDts","_audioMeta","_videoMeta","_audioSegmentInfoList","_videoSegmentInfoList","_forceFirstIDR","_fillSilentAfterSeek","_mp3UseMpegAudio","firefox","_fillAudioTimestampGap","producer","onDataAvailable","remux","onTrackMetadata","_onTrackMetadataReceived","audioTrack","videoTrack","_calculateDtsBase","_remuxVideo","_remuxAudio","metabox","_mp4Generator2","generateInitSegment","dtsCorrection","firstDts","lastDts","mpegRawTrack","firstSegmentAfterSeek","insertPrefixSilentFrame","mdatbox","mdatBytes","firstSampleOriginalDts","isEmpty","getLastSampleBefore","distance","expectedDts","firstSampleDts","videoSegment","silentUnit","_aacSilent2","getSilentFrame","silentFrameDuration","mp4Samples","sample","sampleDuration","needFillSilentFrames","silentFrames","frameCount","currentDts","round","_silentUnit","intDts","previousFrame","frame","lastFrame","_unit","latest","moofbox","_mergeBoxes","firstPts","lastPts","syncPoint","appendSyncPoint","_i2","Browser","ua","exec","platform_match","matched","majorVersion","platform","versionArray","string","opr","webkit","rv","iemobile","edge","android","_message","Log","tag","FORCE_GLOBAL_TAG","GLOBAL_TAG","ENABLE_CALLBACK","ENABLE_ERROR","warn","log","ENABLE_INFO","ENABLE_WARN","ENABLE_DEBUG","debug","ENABLE_VERBOSE","globalTag","forceGlobalTag","enableVerbose","enableDebug","enableInfo","enableWarn","enableError","_notifyChange","enable","Polyfill","proto","output","source","checkContinuation","checkLength","decodeUTF8","out","String","fromCharCode","ucs4","_ucs","_ucs2"],"mappings":"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","file":"flv.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o postsJSON\n values[1] // => commentsJSON\n\n return values;\n });\n ```\n\n @class Promise\n @param {function} resolver\n Useful for tooling.\n @constructor\n*/\nfunction Promise(resolver) {\n this[PROMISE_ID] = nextId();\n this._result = this._state = undefined;\n this._subscribers = [];\n\n if (noop !== resolver) {\n typeof resolver !== 'function' && needsResolver();\n this instanceof Promise ? initializePromise(this, resolver) : needsNew();\n }\n}\n\nPromise.all = all;\nPromise.race = race;\nPromise.resolve = resolve;\nPromise.reject = reject;\nPromise._setScheduler = setScheduler;\nPromise._setAsap = setAsap;\nPromise._asap = asap;\n\nPromise.prototype = {\n constructor: Promise,\n\n /**\n The primary way of interacting with a promise is through its `then` method,\n which registers callbacks to receive either a promise's eventual value or the\n reason why the promise cannot be fulfilled.\n \n ```js\n findUser().then(function(user){\n // user is available\n }, function(reason){\n // user is unavailable, and you are given the reason why\n });\n ```\n \n Chaining\n --------\n \n The return value of `then` is itself a promise. This second, 'downstream'\n promise is resolved with the return value of the first promise's fulfillment\n or rejection handler, or rejected if the handler throws an exception.\n \n ```js\n findUser().then(function (user) {\n return user.name;\n }, function (reason) {\n return 'default name';\n }).then(function (userName) {\n // If `findUser` fulfilled, `userName` will be the user's name, otherwise it\n // will be `'default name'`\n });\n \n findUser().then(function (user) {\n throw new Error('Found user, but still unhappy');\n }, function (reason) {\n throw new Error('`findUser` rejected and we're unhappy');\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.\n // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.\n });\n ```\n If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.\n \n ```js\n findUser().then(function (user) {\n throw new PedagogicalException('Upstream error');\n }).then(function (value) {\n // never reached\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // The `PedgagocialException` is propagated all the way down to here\n });\n ```\n \n Assimilation\n ------------\n \n Sometimes the value you want to propagate to a downstream promise can only be\n retrieved asynchronously. This can be achieved by returning a promise in the\n fulfillment or rejection handler. The downstream promise will then be pending\n until the returned promise is settled. This is called *assimilation*.\n \n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // The user's comments are now available\n });\n ```\n \n If the assimliated promise rejects, then the downstream promise will also reject.\n \n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // If `findCommentsByAuthor` fulfills, we'll have the value here\n }, function (reason) {\n // If `findCommentsByAuthor` rejects, we'll have the reason here\n });\n ```\n \n Simple Example\n --------------\n \n Synchronous Example\n \n ```javascript\n let result;\n \n try {\n result = findResult();\n // success\n } catch(reason) {\n // failure\n }\n ```\n \n Errback Example\n \n ```js\n findResult(function(result, err){\n if (err) {\n // failure\n } else {\n // success\n }\n });\n ```\n \n Promise Example;\n \n ```javascript\n findResult().then(function(result){\n // success\n }, function(reason){\n // failure\n });\n ```\n \n Advanced Example\n --------------\n \n Synchronous Example\n \n ```javascript\n let author, books;\n \n try {\n author = findAuthor();\n books = findBooksByAuthor(author);\n // success\n } catch(reason) {\n // failure\n }\n ```\n \n Errback Example\n \n ```js\n \n function foundBooks(books) {\n \n }\n \n function failure(reason) {\n \n }\n \n findAuthor(function(author, err){\n if (err) {\n failure(err);\n // failure\n } else {\n try {\n findBoooksByAuthor(author, function(books, err) {\n if (err) {\n failure(err);\n } else {\n try {\n foundBooks(books);\n } catch(reason) {\n failure(reason);\n }\n }\n });\n } catch(error) {\n failure(err);\n }\n // success\n }\n });\n ```\n \n Promise Example;\n \n ```javascript\n findAuthor().\n then(findBooksByAuthor).\n then(function(books){\n // found books\n }).catch(function(reason){\n // something went wrong\n });\n ```\n \n @method then\n @param {Function} onFulfilled\n @param {Function} onRejected\n Useful for tooling.\n @return {Promise}\n */\n then: then,\n\n /**\n `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same\n as the catch block of a try/catch statement.\n \n ```js\n function findAuthor(){\n throw new Error('couldn't find that author');\n }\n \n // synchronous\n try {\n findAuthor();\n } catch(reason) {\n // something went wrong\n }\n \n // async with promises\n findAuthor().catch(function(reason){\n // something went wrong\n });\n ```\n \n @method catch\n @param {Function} onRejection\n Useful for tooling.\n @return {Promise}\n */\n 'catch': function _catch(onRejection) {\n return this.then(null, onRejection);\n }\n};\n\nfunction polyfill() {\n var local = undefined;\n\n if (typeof global !== 'undefined') {\n local = global;\n } else if (typeof self !== 'undefined') {\n local = self;\n } else {\n try {\n local = Function('return this')();\n } catch (e) {\n throw new Error('polyfill failed because global object is unavailable in this environment');\n }\n }\n\n var P = local.Promise;\n\n if (P) {\n var promiseToString = null;\n try {\n promiseToString = Object.prototype.toString.call(P.resolve());\n } catch (e) {\n // silently ignored\n }\n\n if (promiseToString === '[object Promise]' && !P.cast) {\n return;\n }\n }\n\n local.Promise = Promise;\n}\n\n// Strange compat..\nPromise.polyfill = polyfill;\nPromise.Promise = Promise;\n\nreturn Promise;\n\n})));\n//# sourceMappingURL=es6-promise.map\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n args = Array.prototype.slice.call(arguments, 1);\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n args = Array.prototype.slice.call(arguments, 1);\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","var bundleFn = arguments[3];\nvar sources = arguments[4];\nvar cache = arguments[5];\n\nvar stringify = JSON.stringify;\n\nmodule.exports = function (fn, options) {\n var wkey;\n var cacheKeys = Object.keys(cache);\n\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n var exp = cache[key].exports;\n // Using babel as a transpiler to use esmodule, the export will always\n // be an object with the default export as a property of it. To ensure\n // the existing api and babel esmodule exports are both supported we\n // check for both\n if (exp === fn || exp && exp.default === fn) {\n wkey = key;\n break;\n }\n }\n\n if (!wkey) {\n wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n var wcache = {};\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n wcache[key] = key;\n }\n sources[wkey] = [\n Function(['require','module','exports'], '(' + fn + ')(self)'),\n wcache\n ];\n }\n var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n\n var scache = {}; scache[wkey] = wkey;\n sources[skey] = [\n Function(['require'], (\n // try to call default if defined to also support babel esmodule\n // exports\n 'var f = require(' + stringify(wkey) + ');' +\n '(f.default ? f.default : f)(self);'\n )),\n scache\n ];\n\n var workerSources = {};\n resolveSources(skey);\n\n function resolveSources(key) {\n workerSources[key] = true;\n\n for (var depPath in sources[key][1]) {\n var depKey = sources[key][1][depPath];\n if (!workerSources[depKey]) {\n resolveSources(depKey);\n }\n }\n }\n\n var src = '(' + bundleFn + ')({'\n + Object.keys(workerSources).map(function (key) {\n return stringify(key) + ':['\n + sources[key][0]\n + ',' + stringify(sources[key][1]) + ']'\n ;\n }).join(',')\n + '},{},[' + stringify(skey) + '])'\n ;\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n var blob = new Blob([src], { type: 'text/javascript' });\n if (options && options.bare) { return blob; }\n var workerUrl = URL.createObjectURL(blob);\n var worker = new Worker(workerUrl);\n worker.objectURL = workerUrl;\n return worker;\n};\n","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const defaultConfig = {\n enableWorker: false,\n enableStashBuffer: true,\n stashInitialSize: undefined,\n\n isLive: false,\n\n lazyLoad: true,\n lazyLoadMaxDuration: 3 * 60,\n lazyLoadRecoverDuration: 30,\n deferLoadAfterSourceOpen: true,\n\n // autoCleanupSourceBuffer: default as false, leave unspecified\n autoCleanupMaxBackwardDuration: 3 * 60,\n autoCleanupMinBackwardDuration: 2 * 60,\n\n statisticsInfoReportInterval: 600,\n\n fixAudioTimestampGap: true,\n\n accurateSeek: false,\n seekType: 'range', // [range, param, custom]\n seekParamStart: 'bstart',\n seekParamEnd: 'bend',\n rangeLoadZeroStart: false,\n customSeekHandler: undefined,\n reuseRedirectedURL: false\n // referrerPolicy: leave as unspecified\n};\n\nexport function createDefaultConfig() {\n return Object.assign({}, defaultConfig);\n}","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport IOController from '../io/io-controller.js';\nimport {createDefaultConfig} from '../config.js';\n\nclass Features {\n\n static supportMSEH264Playback() {\n return window.MediaSource &&\n window.MediaSource.isTypeSupported('video/mp4; codecs=\"avc1.42E01E,mp4a.40.2\"');\n }\n\n static supportNetworkStreamIO() {\n let ioctl = new IOController({}, createDefaultConfig());\n let loaderType = ioctl.loaderType;\n ioctl.destroy();\n return loaderType == 'fetch-stream-loader' || loaderType == 'xhr-moz-chunked-loader';\n }\n\n static getNetworkLoaderTypeName() {\n let ioctl = new IOController({}, createDefaultConfig());\n let loaderType = ioctl.loaderType;\n ioctl.destroy();\n return loaderType;\n }\n\n static supportNativeMediaPlayback(mimeType) {\n if (Features.videoElement == undefined) {\n Features.videoElement = window.document.createElement('video');\n }\n let canPlay = Features.videoElement.canPlayType(mimeType);\n return canPlay === 'probably' || canPlay == 'maybe';\n }\n\n static getFeatureList() {\n let features = {\n mseFlvPlayback: false,\n mseLiveFlvPlayback: false,\n networkStreamIO: false,\n networkLoaderName: '',\n nativeMP4H264Playback: false,\n nativeWebmVP8Playback: false,\n nativeWebmVP9Playback: false\n };\n\n features.mseFlvPlayback = Features.supportMSEH264Playback();\n features.networkStreamIO = Features.supportNetworkStreamIO();\n features.networkLoaderName = Features.getNetworkLoaderTypeName();\n features.mseLiveFlvPlayback = features.mseFlvPlayback && features.networkStreamIO;\n features.nativeMP4H264Playback = Features.supportNativeMediaPlayback('video/mp4; codecs=\"avc1.42001E, mp4a.40.2\"');\n features.nativeWebmVP8Playback = Features.supportNativeMediaPlayback('video/webm; codecs=\"vp8.0, vorbis\"');\n features.nativeWebmVP9Playback = Features.supportNativeMediaPlayback('video/webm; codecs=\"vp9\"');\n\n return features;\n }\n\n}\n\nexport default Features;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass MediaInfo {\n\n constructor() {\n this.mimeType = null;\n this.duration = null;\n\n this.hasAudio = null;\n this.hasVideo = null;\n this.audioCodec = null;\n this.videoCodec = null;\n this.audioDataRate = null;\n this.videoDataRate = null;\n\n this.audioSampleRate = null;\n this.audioChannelCount = null;\n\n this.width = null;\n this.height = null;\n this.fps = null;\n this.profile = null;\n this.level = null;\n this.chromaFormat = null;\n this.sarNum = null;\n this.sarDen = null;\n\n this.metadata = null;\n this.segments = null; // MediaInfo[]\n this.segmentCount = null;\n this.hasKeyframesIndex = null;\n this.keyframesIndex = null;\n }\n\n isComplete() {\n let audioInfoComplete = (this.hasAudio === false) ||\n (this.hasAudio === true &&\n this.audioCodec != null &&\n this.audioSampleRate != null &&\n this.audioChannelCount != null);\n\n let videoInfoComplete = (this.hasVideo === false) ||\n (this.hasVideo === true &&\n this.videoCodec != null &&\n this.width != null &&\n this.height != null &&\n this.fps != null &&\n this.profile != null &&\n this.level != null &&\n this.chromaFormat != null &&\n this.sarNum != null &&\n this.sarDen != null);\n\n // keyframesIndex may not be present\n return this.mimeType != null &&\n this.duration != null &&\n this.metadata != null &&\n this.hasKeyframesIndex != null &&\n audioInfoComplete &&\n videoInfoComplete;\n }\n\n isSeekable() {\n return this.hasKeyframesIndex === true;\n }\n\n getNearestKeyframe(milliseconds) {\n if (this.keyframesIndex == null) {\n return null;\n }\n\n let table = this.keyframesIndex;\n let keyframeIdx = this._search(table.times, milliseconds);\n\n return {\n index: keyframeIdx,\n milliseconds: table.times[keyframeIdx],\n fileposition: table.filepositions[keyframeIdx]\n };\n }\n\n _search(list, value) {\n let idx = 0;\n\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (value < list[0]) {\n idx = 0;\n lbound = ubound + 1; // skip search\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (value >= list[mid] && value < list[mid + 1])) {\n idx = mid;\n break;\n } else if (list[mid] < value) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n\n return idx;\n }\n\n}\n\nexport default MediaInfo;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Represents an media sample (audio / video)\nexport class SampleInfo {\n\n constructor(dts, pts, duration, originalDts, isSync) {\n this.dts = dts;\n this.pts = pts;\n this.duration = duration;\n this.originalDts = originalDts;\n this.isSyncPoint = isSync;\n this.fileposition = null;\n }\n\n}\n\n// Media Segment concept is defined in Media Source Extensions spec.\n// Particularly in ISO BMFF format, an Media Segment contains a moof box followed by a mdat box.\nexport class MediaSegmentInfo {\n\n constructor() {\n this.beginDts = 0;\n this.endDts = 0;\n this.beginPts = 0;\n this.endPts = 0;\n this.originalBeginDts = 0;\n this.originalEndDts = 0;\n this.syncPoints = []; // SampleInfo[n], for video IDR frames only\n this.firstSample = null; // SampleInfo\n this.lastSample = null; // SampleInfo\n }\n\n appendSyncPoint(sampleInfo) { // also called Random Access Point\n sampleInfo.isSyncPoint = true;\n this.syncPoints.push(sampleInfo);\n }\n\n}\n\n// Ordered list for recording video IDR frames, sorted by originalDts\nexport class IDRSampleList {\n\n constructor() {\n this._list = [];\n }\n\n clear() {\n this._list = [];\n }\n\n appendArray(syncPoints) {\n let list = this._list;\n\n if (syncPoints.length === 0) {\n return;\n }\n\n if (list.length > 0 && syncPoints[0].originalDts < list[list.length - 1].originalDts) {\n this.clear();\n }\n\n Array.prototype.push.apply(list, syncPoints);\n }\n\n getLastSyncPointBeforeDts(dts) {\n if (this._list.length == 0) {\n return null;\n }\n\n let list = this._list;\n let idx = 0;\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (dts < list[0].dts) {\n idx = 0;\n lbound = ubound + 1;\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (dts >= list[mid].dts && dts < list[mid + 1].dts)) {\n idx = mid;\n break;\n } else if (list[mid].dts < dts) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n return this._list[idx];\n }\n\n}\n\n// Data structure for recording information of media segments in single track.\nexport class MediaSegmentInfoList {\n\n constructor(type) {\n this._type = type;\n this._list = [];\n this._lastAppendLocation = -1; // cached last insert location\n }\n\n get type() {\n return this._type;\n }\n\n get length() {\n return this._list.length;\n }\n\n isEmpty() {\n return this._list.length === 0;\n }\n\n clear() {\n this._list = [];\n this._lastAppendLocation = -1;\n }\n\n _searchNearestSegmentBefore(originalBeginDts) {\n let list = this._list;\n if (list.length === 0) {\n return -2;\n }\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n let idx = 0;\n\n if (originalBeginDts < list[0].originalBeginDts) {\n idx = -1;\n return idx;\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (originalBeginDts > list[mid].lastSample.originalDts &&\n (originalBeginDts < list[mid + 1].originalBeginDts))) {\n idx = mid;\n break;\n } else if (list[mid].originalBeginDts < originalBeginDts) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n return idx;\n }\n\n _searchNearestSegmentAfter(originalBeginDts) {\n return this._searchNearestSegmentBefore(originalBeginDts) + 1;\n }\n\n append(mediaSegmentInfo) {\n let list = this._list;\n let msi = mediaSegmentInfo;\n let lastAppendIdx = this._lastAppendLocation;\n let insertIdx = 0;\n\n if (lastAppendIdx !== -1 && lastAppendIdx < list.length &&\n msi.originalBeginDts >= list[lastAppendIdx].lastSample.originalDts &&\n ((lastAppendIdx === list.length - 1) ||\n (lastAppendIdx < list.length - 1 &&\n msi.originalBeginDts < list[lastAppendIdx + 1].originalBeginDts))) {\n insertIdx = lastAppendIdx + 1; // use cached location idx\n } else {\n if (list.length > 0) {\n insertIdx = this._searchNearestSegmentBefore(msi.originalBeginDts) + 1;\n }\n }\n\n this._lastAppendLocation = insertIdx;\n this._list.splice(insertIdx, 0, msi);\n }\n\n getLastSegmentBefore(originalBeginDts) {\n let idx = this._searchNearestSegmentBefore(originalBeginDts);\n if (idx >= 0) {\n return this._list[idx];\n } else { // -1\n return null;\n }\n }\n\n getLastSampleBefore(originalBeginDts) {\n let segment = this.getLastSegmentBefore(originalBeginDts);\n if (segment != null) {\n return segment.lastSample;\n } else {\n return null;\n }\n }\n\n getLastSyncPointBefore(originalBeginDts) {\n let segmentIdx = this._searchNearestSegmentBefore(originalBeginDts);\n let syncPoints = this._list[segmentIdx].syncPoints;\n while (syncPoints.length === 0 && segmentIdx > 0) {\n segmentIdx--;\n syncPoints = this._list[segmentIdx].syncPoints;\n }\n if (syncPoints.length > 0) {\n return syncPoints[syncPoints.length - 1];\n } else {\n return null;\n }\n }\n\n}","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport MSEEvents from './mse-events.js';\nimport {SampleInfo, IDRSampleList} from './media-segment-info.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\n// Media Source Extensions controller\nclass MSEController {\n\n constructor(config) {\n this.TAG = 'MSEController';\n\n this._config = config;\n this._emitter = new EventEmitter();\n\n if (this._config.isLive && this._config.autoCleanupSourceBuffer == undefined) {\n // For live stream, do auto cleanup by default\n this._config.autoCleanupSourceBuffer = true;\n }\n\n this.e = {\n onSourceOpen: this._onSourceOpen.bind(this),\n onSourceEnded: this._onSourceEnded.bind(this),\n onSourceClose: this._onSourceClose.bind(this),\n onSourceBufferError: this._onSourceBufferError.bind(this),\n onSourceBufferUpdateEnd: this._onSourceBufferUpdateEnd.bind(this)\n };\n\n this._mediaSource = null;\n this._mediaSourceObjectURL = null;\n this._mediaElement = null;\n\n this._isBufferFull = false;\n this._hasPendingEos = false;\n\n this._requireSetMediaDuration = false;\n this._pendingMediaDuration = 0;\n\n this._pendingSourceBufferInit = [];\n this._mimeTypes = {\n video: null,\n audio: null\n };\n this._sourceBuffers = {\n video: null,\n audio: null\n };\n this._lastInitSegments = {\n video: null,\n audio: null\n };\n this._pendingSegments = {\n video: [],\n audio: []\n };\n this._pendingRemoveRanges = {\n video: [],\n audio: []\n };\n this._idrList = new IDRSampleList();\n }\n\n destroy() {\n if (this._mediaElement || this._mediaSource) {\n this.detachMediaElement();\n }\n this.e = null;\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n attachMediaElement(mediaElement) {\n if (this._mediaSource) {\n throw new IllegalStateException('MediaSource has been attached to an HTMLMediaElement!');\n }\n let ms = this._mediaSource = new window.MediaSource();\n ms.addEventListener('sourceopen', this.e.onSourceOpen);\n ms.addEventListener('sourceended', this.e.onSourceEnded);\n ms.addEventListener('sourceclose', this.e.onSourceClose);\n\n this._mediaElement = mediaElement;\n this._mediaSourceObjectURL = window.URL.createObjectURL(this._mediaSource);\n mediaElement.src = this._mediaSourceObjectURL;\n }\n\n detachMediaElement() {\n if (this._mediaSource) {\n let ms = this._mediaSource;\n for (let type in this._sourceBuffers) {\n // pending segments should be discard\n let ps = this._pendingSegments[type];\n ps.splice(0, ps.length);\n this._pendingSegments[type] = null;\n this._pendingRemoveRanges[type] = null;\n this._lastInitSegments[type] = null;\n\n // remove all sourcebuffers\n let sb = this._sourceBuffers[type];\n if (sb) {\n if (ms.readyState !== 'closed') {\n ms.removeSourceBuffer(sb);\n sb.removeEventListener('error', this.e.onSourceBufferError);\n sb.removeEventListener('updateend', this.e.onSourceBufferUpdateEnd);\n }\n this._mimeTypes[type] = null;\n this._sourceBuffers[type] = null;\n }\n }\n if (ms.readyState === 'open') {\n try {\n ms.endOfStream();\n } catch (error) {\n Log.e(this.TAG, error.message);\n }\n }\n ms.removeEventListener('sourceopen', this.e.onSourceOpen);\n ms.removeEventListener('sourceended', this.e.onSourceEnded);\n ms.removeEventListener('sourceclose', this.e.onSourceClose);\n this._pendingSourceBufferInit = [];\n this._isBufferFull = false;\n this._idrList.clear();\n this._mediaSource = null;\n }\n\n if (this._mediaElement) {\n this._mediaElement.src = '';\n this._mediaElement.removeAttribute('src');\n this._mediaElement = null;\n }\n if (this._mediaSourceObjectURL) {\n window.URL.revokeObjectURL(this._mediaSourceObjectURL);\n this._mediaSourceObjectURL = null;\n }\n }\n\n appendInitSegment(initSegment, deferred) {\n if (!this._mediaSource || this._mediaSource.readyState !== 'open') {\n // sourcebuffer creation requires mediaSource.readyState === 'open'\n // so we defer the sourcebuffer creation, until sourceopen event triggered\n this._pendingSourceBufferInit.push(initSegment);\n // make sure that this InitSegment is in the front of pending segments queue\n this._pendingSegments[initSegment.type].push(initSegment);\n return;\n }\n\n let is = initSegment;\n let mimeType = `${is.container}`;\n if (is.codec && is.codec.length > 0) {\n mimeType += `;codecs=${is.codec}`;\n }\n\n let firstInitSegment = false;\n\n Log.v(this.TAG, 'Received Initialization Segment, mimeType: ' + mimeType);\n this._lastInitSegments[is.type] = is;\n\n if (mimeType !== this._mimeTypes[is.type]) {\n if (!this._mimeTypes[is.type]) { // empty, first chance create sourcebuffer\n firstInitSegment = true;\n try {\n let sb = this._sourceBuffers[is.type] = this._mediaSource.addSourceBuffer(mimeType);\n sb.addEventListener('error', this.e.onSourceBufferError);\n sb.addEventListener('updateend', this.e.onSourceBufferUpdateEnd);\n } catch (error) {\n Log.e(this.TAG, error.message);\n this._emitter.emit(MSEEvents.ERROR, {code: error.code, msg: error.message});\n return;\n }\n } else {\n Log.v(this.TAG, `Notice: ${is.type} mimeType changed, origin: ${this._mimeTypes[is.type]}, target: ${mimeType}`);\n }\n this._mimeTypes[is.type] = mimeType;\n }\n\n if (!deferred) {\n // deferred means this InitSegment has been pushed to pendingSegments queue\n this._pendingSegments[is.type].push(is);\n }\n if (!firstInitSegment) { // append immediately only if init segment in subsequence\n if (this._sourceBuffers[is.type] && !this._sourceBuffers[is.type].updating) {\n this._doAppendSegments();\n }\n }\n if (Browser.safari && is.container === 'audio/mpeg' && is.mediaDuration > 0) {\n // 'audio/mpeg' track under Safari may cause MediaElement's duration to be NaN\n // Manually correct MediaSource.duration to make progress bar seekable, and report right duration\n this._requireSetMediaDuration = true;\n this._pendingMediaDuration = is.mediaDuration / 1000; // in seconds\n this._updateMediaSourceDuration();\n }\n }\n\n appendMediaSegment(mediaSegment) {\n let ms = mediaSegment;\n this._pendingSegments[ms.type].push(ms);\n\n if (this._config.autoCleanupSourceBuffer && this._needCleanupSourceBuffer()) {\n this._doCleanupSourceBuffer();\n }\n\n let sb = this._sourceBuffers[ms.type];\n if (sb && !sb.updating && !this._hasPendingRemoveRanges()) {\n this._doAppendSegments();\n }\n }\n\n seek(seconds) {\n // remove all appended buffers\n for (let type in this._sourceBuffers) {\n if (!this._sourceBuffers[type]) {\n continue;\n }\n\n // abort current buffer append algorithm\n let sb = this._sourceBuffers[type];\n if (this._mediaSource.readyState === 'open') {\n try {\n // If range removal algorithm is running, InvalidStateError will be throwed\n // Ignore it.\n sb.abort();\n } catch (error) {\n Log.e(this.TAG, error.message);\n }\n }\n\n // IDRList should be clear\n this._idrList.clear();\n\n // pending segments should be discard\n let ps = this._pendingSegments[type];\n ps.splice(0, ps.length);\n\n if (this._mediaSource.readyState === 'closed') {\n // Parent MediaSource object has been detached from HTMLMediaElement\n continue;\n }\n\n // record ranges to be remove from SourceBuffer\n for (let i = 0; i < sb.buffered.length; i++) {\n let start = sb.buffered.start(i);\n let end = sb.buffered.end(i);\n this._pendingRemoveRanges[type].push({start, end});\n }\n\n // if sb is not updating, let's remove ranges now!\n if (!sb.updating) {\n this._doRemoveRanges();\n }\n\n // Safari 10 may get InvalidStateError in the later appendBuffer() after SourceBuffer.remove() call\n // Internal parser's state may be invalid at this time. Re-append last InitSegment to workaround.\n // Related issue: https://bugs.webkit.org/show_bug.cgi?id=159230\n if (Browser.safari) {\n let lastInitSegment = this._lastInitSegments[type];\n if (lastInitSegment) {\n this._pendingSegments[type].push(lastInitSegment);\n if (!sb.updating) {\n this._doAppendSegments();\n }\n }\n }\n }\n }\n\n endOfStream() {\n let ms = this._mediaSource;\n let sb = this._sourceBuffers;\n if (!ms || ms.readyState !== 'open') {\n if (ms && ms.readyState === 'closed' && this._hasPendingSegments()) {\n // If MediaSource hasn't turned into open state, and there're pending segments\n // Mark pending endOfStream, defer call until all pending segments appended complete\n this._hasPendingEos = true;\n }\n return;\n }\n if (sb.video && sb.video.updating || sb.audio && sb.audio.updating) {\n // If any sourcebuffer is updating, defer endOfStream operation\n // See _onSourceBufferUpdateEnd()\n this._hasPendingEos = true;\n } else {\n this._hasPendingEos = false;\n // Notify media data loading complete\n // This is helpful for correcting total duration to match last media segment\n // Otherwise MediaElement's ended event may not be triggered\n ms.endOfStream();\n }\n }\n\n getNearestKeyframe(dts) {\n return this._idrList.getLastSyncPointBeforeDts(dts);\n }\n\n _needCleanupSourceBuffer() {\n if (!this._config.autoCleanupSourceBuffer) {\n return false;\n }\n\n let currentTime = this._mediaElement.currentTime;\n\n for (let type in this._sourceBuffers) {\n let sb = this._sourceBuffers[type];\n if (sb) {\n let buffered = sb.buffered;\n if (buffered.length >= 1) {\n if (currentTime - buffered.start(0) >= this._config.autoCleanupMaxBackwardDuration) {\n return true;\n }\n }\n }\n }\n\n return false;\n }\n\n _doCleanupSourceBuffer() {\n let currentTime = this._mediaElement.currentTime;\n\n for (let type in this._sourceBuffers) {\n let sb = this._sourceBuffers[type];\n if (sb) {\n let buffered = sb.buffered;\n let doRemove = false;\n\n for (let i = 0; i < buffered.length; i++) {\n let start = buffered.start(i);\n let end = buffered.end(i);\n\n if (start <= currentTime && currentTime < end + 3) { // padding 3 seconds\n if (currentTime - start >= this._config.autoCleanupMaxBackwardDuration) {\n doRemove = true;\n let removeEnd = currentTime - this._config.autoCleanupMinBackwardDuration;\n this._pendingRemoveRanges[type].push({start: start, end: removeEnd});\n }\n } else if (end < currentTime) {\n doRemove = true;\n this._pendingRemoveRanges[type].push({start: start, end: end});\n }\n }\n\n if (doRemove && !sb.updating) {\n this._doRemoveRanges();\n }\n }\n }\n }\n\n _updateMediaSourceDuration() {\n let sb = this._sourceBuffers;\n if (this._mediaElement.readyState === 0 || this._mediaSource.readyState !== 'open') {\n return;\n }\n if ((sb.video && sb.video.updating) || (sb.audio && sb.audio.updating)) {\n return;\n }\n\n let current = this._mediaSource.duration;\n let target = this._pendingMediaDuration;\n\n if (target > 0 && (isNaN(current) || target > current)) {\n Log.v(this.TAG, `Update MediaSource duration from ${current} to ${target}`);\n this._mediaSource.duration = target;\n }\n\n this._requireSetMediaDuration = false;\n this._pendingMediaDuration = 0;\n }\n\n _doRemoveRanges() {\n for (let type in this._pendingRemoveRanges) {\n if (!this._sourceBuffers[type] || this._sourceBuffers[type].updating) {\n continue;\n }\n let sb = this._sourceBuffers[type];\n let ranges = this._pendingRemoveRanges[type];\n while (ranges.length && !sb.updating) {\n let range = ranges.shift();\n sb.remove(range.start, range.end);\n }\n }\n }\n\n _doAppendSegments() {\n let pendingSegments = this._pendingSegments;\n\n for (let type in pendingSegments) {\n if (!this._sourceBuffers[type] || this._sourceBuffers[type].updating) {\n continue;\n }\n\n if (pendingSegments[type].length > 0) {\n let segment = pendingSegments[type].shift();\n\n if (segment.timestampOffset) {\n // For MPEG audio stream in MSE, if unbuffered-seeking occurred\n // We need explicitly set timestampOffset to the desired point in timeline for mpeg SourceBuffer.\n let currentOffset = this._sourceBuffers[type].timestampOffset;\n let targetOffset = segment.timestampOffset / 1000; // in seconds\n\n let delta = Math.abs(currentOffset - targetOffset);\n if (delta > 0.1) { // If time delta > 100ms\n Log.v(this.TAG, `Update MPEG audio timestampOffset from ${currentOffset} to ${targetOffset}`);\n this._sourceBuffers[type].timestampOffset = targetOffset;\n }\n delete segment.timestampOffset;\n }\n\n if (!segment.data || segment.data.byteLength === 0) {\n // Ignore empty buffer\n continue;\n }\n\n try {\n this._sourceBuffers[type].appendBuffer(segment.data);\n this._isBufferFull = false;\n if (type === 'video' && segment.hasOwnProperty('info')) {\n this._idrList.appendArray(segment.info.syncPoints);\n }\n } catch (error) {\n this._pendingSegments[type].unshift(segment);\n if (error.code === 22) { // QuotaExceededError\n /* Notice that FireFox may not throw QuotaExceededError if SourceBuffer is full\n * Currently we can only do lazy-load to avoid SourceBuffer become scattered.\n * SourceBuffer eviction policy may be changed in future version of FireFox.\n *\n * Related issues:\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1279885\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1280023\n */\n\n // report buffer full, abort network IO\n if (!this._isBufferFull) {\n this._emitter.emit(MSEEvents.BUFFER_FULL);\n }\n this._isBufferFull = true;\n } else {\n Log.e(this.TAG, error.message);\n this._emitter.emit(MSEEvents.ERROR, {code: error.code, msg: error.message});\n }\n }\n }\n }\n }\n\n _onSourceOpen() {\n Log.v(this.TAG, 'MediaSource onSourceOpen');\n this._mediaSource.removeEventListener('sourceopen', this.e.onSourceOpen);\n // deferred sourcebuffer creation / initialization\n if (this._pendingSourceBufferInit.length > 0) {\n let pendings = this._pendingSourceBufferInit;\n while (pendings.length) {\n let segment = pendings.shift();\n this.appendInitSegment(segment, true);\n }\n }\n // there may be some pending media segments, append them\n if (this._hasPendingSegments()) {\n this._doAppendSegments();\n }\n this._emitter.emit(MSEEvents.SOURCE_OPEN);\n }\n\n _onSourceEnded() {\n // fired on endOfStream\n Log.v(this.TAG, 'MediaSource onSourceEnded');\n }\n\n _onSourceClose() {\n // fired on detaching from media element\n Log.v(this.TAG, 'MediaSource onSourceClose');\n if (this._mediaSource && this.e != null) {\n this._mediaSource.removeEventListener('sourceopen', this.e.onSourceOpen);\n this._mediaSource.removeEventListener('sourceended', this.e.onSourceEnded);\n this._mediaSource.removeEventListener('sourceclose', this.e.onSourceClose);\n }\n }\n\n _hasPendingSegments() {\n let ps = this._pendingSegments;\n return ps.video.length > 0 || ps.audio.length > 0;\n }\n\n _hasPendingRemoveRanges() {\n let prr = this._pendingRemoveRanges;\n return prr.video.length > 0 || prr.audio.length > 0;\n }\n\n _onSourceBufferUpdateEnd() {\n if (this._requireSetMediaDuration) {\n this._updateMediaSourceDuration();\n } else if (this._hasPendingRemoveRanges()) {\n this._doRemoveRanges();\n } else if (this._hasPendingSegments()) {\n this._doAppendSegments();\n } else if (this._hasPendingEos) {\n this.endOfStream();\n }\n this._emitter.emit(MSEEvents.UPDATE_END);\n }\n\n _onSourceBufferError(e) {\n Log.e(this.TAG, `SourceBuffer Error: ${e}`);\n // this error might not always be fatal, just ignore it\n }\n\n}\n\nexport default MSEController;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst MSEEvents = {\n ERROR: 'error',\n SOURCE_OPEN: 'source_open',\n UPDATE_END: 'update_end',\n BUFFER_FULL: 'buffer_full'\n};\n\nexport default MSEEvents;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport LoggingControl from '../utils/logging-control.js';\nimport TransmuxingController from './transmuxing-controller.js';\nimport TransmuxingEvents from './transmuxing-events.js';\nimport TransmuxingWorker from './transmuxing-worker.js';\nimport MediaInfo from './media-info.js';\n\nclass Transmuxer {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'Transmuxer';\n this._emitter = new EventEmitter();\n\n if (config.enableWorker && typeof (Worker) !== 'undefined') {\n try {\n let work = require('webworkify');\n this._worker = work(TransmuxingWorker);\n this._workerDestroying = false;\n this._worker.addEventListener('message', this._onWorkerMessage.bind(this));\n this._worker.postMessage({cmd: 'init', param: [mediaDataSource, config]});\n this.e = {\n onLoggingConfigChanged: this._onLoggingConfigChanged.bind(this)\n };\n LoggingControl.registerListener(this.e.onLoggingConfigChanged);\n this._worker.postMessage({cmd: 'logging_config', param: LoggingControl.getConfig()});\n } catch (error) {\n Log.e(this.TAG, 'Error while initialize transmuxing worker, fallback to inline transmuxing');\n this._worker = null;\n this._controller = new TransmuxingController(mediaDataSource, config);\n }\n } else {\n this._controller = new TransmuxingController(mediaDataSource, config);\n }\n\n if (this._controller) {\n let ctl = this._controller;\n ctl.on(TransmuxingEvents.IO_ERROR, this._onIOError.bind(this));\n ctl.on(TransmuxingEvents.DEMUX_ERROR, this._onDemuxError.bind(this));\n ctl.on(TransmuxingEvents.INIT_SEGMENT, this._onInitSegment.bind(this));\n ctl.on(TransmuxingEvents.MEDIA_SEGMENT, this._onMediaSegment.bind(this));\n ctl.on(TransmuxingEvents.LOADING_COMPLETE, this._onLoadingComplete.bind(this));\n ctl.on(TransmuxingEvents.RECOVERED_EARLY_EOF, this._onRecoveredEarlyEof.bind(this));\n ctl.on(TransmuxingEvents.MEDIA_INFO, this._onMediaInfo.bind(this));\n ctl.on(TransmuxingEvents.STATISTICS_INFO, this._onStatisticsInfo.bind(this));\n ctl.on(TransmuxingEvents.RECOMMEND_SEEKPOINT, this._onRecommendSeekpoint.bind(this));\n }\n }\n\n destroy() {\n if (this._worker) {\n if (!this._workerDestroying) {\n this._workerDestroying = true;\n this._worker.postMessage({cmd: 'destroy'});\n LoggingControl.removeListener(this.e.onLoggingConfigChanged);\n this.e = null;\n }\n } else {\n this._controller.destroy();\n this._controller = null;\n }\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n hasWorker() {\n return this._worker != null;\n }\n\n open() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'start'});\n } else {\n this._controller.start();\n }\n }\n\n close() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'stop'});\n } else {\n this._controller.stop();\n }\n }\n\n seek(milliseconds) {\n if (this._worker) {\n this._worker.postMessage({cmd: 'seek', param: milliseconds});\n } else {\n this._controller.seek(milliseconds);\n }\n }\n\n pause() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'pause'});\n } else {\n this._controller.pause();\n }\n }\n\n resume() {\n if (this._worker) {\n this._worker.postMessage({cmd: 'resume'});\n } else {\n this._controller.resume();\n }\n }\n\n _onInitSegment(type, initSegment) {\n // do async invoke\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.INIT_SEGMENT, type, initSegment);\n });\n }\n\n _onMediaSegment(type, mediaSegment) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.MEDIA_SEGMENT, type, mediaSegment);\n });\n }\n\n _onLoadingComplete() {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.LOADING_COMPLETE);\n });\n }\n\n _onRecoveredEarlyEof() {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.RECOVERED_EARLY_EOF);\n });\n }\n\n _onMediaInfo(mediaInfo) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.MEDIA_INFO, mediaInfo);\n });\n }\n\n _onStatisticsInfo(statisticsInfo) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.STATISTICS_INFO, statisticsInfo);\n });\n }\n\n _onIOError(type, info) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.IO_ERROR, type, info);\n });\n }\n\n _onDemuxError(type, info) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.DEMUX_ERROR, type, info);\n });\n }\n\n _onRecommendSeekpoint(milliseconds) {\n Promise.resolve().then(() => {\n this._emitter.emit(TransmuxingEvents.RECOMMEND_SEEKPOINT, milliseconds);\n });\n }\n\n _onLoggingConfigChanged(config) {\n if (this._worker) {\n this._worker.postMessage({cmd: 'logging_config', param: config});\n }\n }\n\n _onWorkerMessage(e) {\n let message = e.data;\n let data = message.data;\n\n if (message.msg === 'destroyed' || this._workerDestroying) {\n this._workerDestroying = false;\n this._worker.terminate();\n this._worker = null;\n return;\n }\n\n switch (message.msg) {\n case TransmuxingEvents.INIT_SEGMENT:\n case TransmuxingEvents.MEDIA_SEGMENT:\n this._emitter.emit(message.msg, data.type, data.data);\n break;\n case TransmuxingEvents.LOADING_COMPLETE:\n case TransmuxingEvents.RECOVERED_EARLY_EOF:\n this._emitter.emit(message.msg);\n break;\n case TransmuxingEvents.MEDIA_INFO:\n Object.setPrototypeOf(data, MediaInfo.prototype);\n this._emitter.emit(message.msg, data);\n break;\n case TransmuxingEvents.STATISTICS_INFO:\n this._emitter.emit(message.msg, data);\n break;\n case TransmuxingEvents.IO_ERROR:\n case TransmuxingEvents.DEMUX_ERROR:\n this._emitter.emit(message.msg, data.type, data.info);\n break;\n case TransmuxingEvents.RECOMMEND_SEEKPOINT:\n this._emitter.emit(message.msg, data);\n break;\n case 'logcat_callback':\n Log.emitter.emit('log', data.type, data.logcat);\n break;\n default:\n break;\n }\n }\n\n}\n\nexport default Transmuxer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport MediaInfo from './media-info.js';\nimport FLVDemuxer from '../demux/flv-demuxer.js';\nimport MP4Remuxer from '../remux/mp4-remuxer.js';\nimport DemuxErrors from '../demux/demux-errors.js';\nimport IOController from '../io/io-controller.js';\nimport TransmuxingEvents from './transmuxing-events.js';\nimport {LoaderStatus, LoaderErrors} from '../io/loader.js';\n\n// Transmuxing (IO, Demuxing, Remuxing) controller, with multipart support\nclass TransmuxingController {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'TransmuxingController';\n this._emitter = new EventEmitter();\n\n this._config = config;\n\n // treat single part media as multipart media, which has only one segment\n if (!mediaDataSource.segments) {\n mediaDataSource.segments = [{\n duration: mediaDataSource.duration,\n filesize: mediaDataSource.filesize,\n url: mediaDataSource.url\n }];\n }\n\n // fill in default IO params if not exists\n if (typeof mediaDataSource.cors !== 'boolean') {\n mediaDataSource.cors = true;\n }\n if (typeof mediaDataSource.withCredentials !== 'boolean') {\n mediaDataSource.withCredentials = false;\n }\n\n this._mediaDataSource = mediaDataSource;\n this._currentSegmentIndex = 0;\n let totalDuration = 0;\n\n this._mediaDataSource.segments.forEach((segment) => {\n // timestampBase for each segment, and calculate total duration\n segment.timestampBase = totalDuration;\n totalDuration += segment.duration;\n // params needed by IOController\n segment.cors = mediaDataSource.cors;\n segment.withCredentials = mediaDataSource.withCredentials;\n // referrer policy control, if exist\n if (config.referrerPolicy) {\n segment.referrerPolicy = config.referrerPolicy;\n }\n });\n\n if (!isNaN(totalDuration) && this._mediaDataSource.duration !== totalDuration) {\n this._mediaDataSource.duration = totalDuration;\n }\n\n this._mediaInfo = null;\n this._demuxer = null;\n this._remuxer = null;\n this._ioctl = null;\n\n this._pendingSeekTime = null;\n this._pendingResolveSeekPoint = null;\n\n this._statisticsReporter = null;\n }\n\n destroy() {\n this._mediaInfo = null;\n this._mediaDataSource = null;\n\n if (this._statisticsReporter) {\n this._disableStatisticsReporter();\n }\n if (this._ioctl) {\n this._ioctl.destroy();\n this._ioctl = null;\n }\n if (this._demuxer) {\n this._demuxer.destroy();\n this._demuxer = null;\n }\n if (this._remuxer) {\n this._remuxer.destroy();\n this._remuxer = null;\n }\n\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n start() {\n this._loadSegment(0);\n this._enableStatisticsReporter();\n }\n\n _loadSegment(segmentIndex, optionalFrom) {\n this._currentSegmentIndex = segmentIndex;\n let dataSource = this._mediaDataSource.segments[segmentIndex];\n\n let ioctl = this._ioctl = new IOController(dataSource, this._config, segmentIndex);\n ioctl.onError = this._onIOException.bind(this);\n ioctl.onSeeked = this._onIOSeeked.bind(this);\n ioctl.onComplete = this._onIOComplete.bind(this);\n ioctl.onRedirect = this._onIORedirect.bind(this);\n ioctl.onRecoveredEarlyEof = this._onIORecoveredEarlyEof.bind(this);\n\n if (optionalFrom) {\n this._demuxer.bindDataSource(this._ioctl);\n } else {\n ioctl.onDataArrival = this._onInitChunkArrival.bind(this);\n }\n\n ioctl.open(optionalFrom);\n }\n\n stop() {\n this._internalAbort();\n this._disableStatisticsReporter();\n }\n\n _internalAbort() {\n if (this._ioctl) {\n this._ioctl.destroy();\n this._ioctl = null;\n }\n }\n\n pause() { // take a rest\n if (this._ioctl && this._ioctl.isWorking()) {\n this._ioctl.pause();\n this._disableStatisticsReporter();\n }\n }\n\n resume() {\n if (this._ioctl && this._ioctl.isPaused()) {\n this._ioctl.resume();\n this._enableStatisticsReporter();\n }\n }\n\n seek(milliseconds) {\n if (this._mediaInfo == null || !this._mediaInfo.isSeekable()) {\n return;\n }\n\n let targetSegmentIndex = this._searchSegmentIndexContains(milliseconds);\n\n if (targetSegmentIndex === this._currentSegmentIndex) {\n // intra-segment seeking\n let segmentInfo = this._mediaInfo.segments[targetSegmentIndex];\n\n if (segmentInfo == undefined) {\n // current segment loading started, but mediainfo hasn't received yet\n // wait for the metadata loaded, then seek to expected position\n this._pendingSeekTime = milliseconds;\n } else {\n let keyframe = segmentInfo.getNearestKeyframe(milliseconds);\n this._remuxer.seek(keyframe.milliseconds);\n this._ioctl.seek(keyframe.fileposition);\n // Will be resolved in _onRemuxerMediaSegmentArrival()\n this._pendingResolveSeekPoint = keyframe.milliseconds;\n }\n } else {\n // cross-segment seeking\n let targetSegmentInfo = this._mediaInfo.segments[targetSegmentIndex];\n\n if (targetSegmentInfo == undefined) {\n // target segment hasn't been loaded. We need metadata then seek to expected time\n this._pendingSeekTime = milliseconds;\n this._internalAbort();\n this._remuxer.seek();\n this._remuxer.insertDiscontinuity();\n this._loadSegment(targetSegmentIndex);\n // Here we wait for the metadata loaded, then seek to expected position\n } else {\n // We have target segment's metadata, direct seek to target position\n let keyframe = targetSegmentInfo.getNearestKeyframe(milliseconds);\n this._internalAbort();\n this._remuxer.seek(milliseconds);\n this._remuxer.insertDiscontinuity();\n this._demuxer.resetMediaInfo();\n this._demuxer.timestampBase = this._mediaDataSource.segments[targetSegmentIndex].timestampBase;\n this._loadSegment(targetSegmentIndex, keyframe.fileposition);\n this._pendingResolveSeekPoint = keyframe.milliseconds;\n this._reportSegmentMediaInfo(targetSegmentIndex);\n }\n }\n\n this._enableStatisticsReporter();\n }\n\n _searchSegmentIndexContains(milliseconds) {\n let segments = this._mediaDataSource.segments;\n let idx = segments.length - 1;\n\n for (let i = 0; i < segments.length; i++) {\n if (milliseconds < segments[i].timestampBase) {\n idx = i - 1;\n break;\n }\n }\n return idx;\n }\n\n _onInitChunkArrival(data, byteStart) {\n let probeData = null;\n let consumed = 0;\n\n if (byteStart > 0) {\n // IOController seeked immediately after opened, byteStart > 0 callback may received\n this._demuxer.bindDataSource(this._ioctl);\n this._demuxer.timestampBase = this._mediaDataSource.segments[this._currentSegmentIndex].timestampBase;\n\n consumed = this._demuxer.parseChunks(data, byteStart);\n } else if ((probeData = FLVDemuxer.probe(data)).match) {\n // Always create new FLVDemuxer\n this._demuxer = new FLVDemuxer(probeData, this._config);\n\n if (!this._remuxer) {\n this._remuxer = new MP4Remuxer(this._config);\n }\n\n let mds = this._mediaDataSource;\n if (mds.duration != undefined && !isNaN(mds.duration)) {\n this._demuxer.overridedDuration = mds.duration;\n }\n if (typeof mds.hasAudio === 'boolean') {\n this._demuxer.overridedHasAudio = mds.hasAudio;\n }\n if (typeof mds.hasVideo === 'boolean') {\n this._demuxer.overridedHasVideo = mds.hasVideo;\n }\n\n this._demuxer.timestampBase = mds.segments[this._currentSegmentIndex].timestampBase;\n\n this._demuxer.onError = this._onDemuxException.bind(this);\n this._demuxer.onMediaInfo = this._onMediaInfo.bind(this);\n\n this._remuxer.bindDataSource(this._demuxer\n .bindDataSource(this._ioctl\n ));\n\n this._remuxer.onInitSegment = this._onRemuxerInitSegmentArrival.bind(this);\n this._remuxer.onMediaSegment = this._onRemuxerMediaSegmentArrival.bind(this);\n\n consumed = this._demuxer.parseChunks(data, byteStart);\n } else {\n probeData = null;\n Log.e(this.TAG, 'Non-FLV, Unsupported media type!');\n Promise.resolve().then(() => {\n this._internalAbort();\n });\n this._emitter.emit(TransmuxingEvents.DEMUX_ERROR, DemuxErrors.FORMAT_UNSUPPORTED, 'Non-FLV, Unsupported media type');\n\n consumed = 0;\n }\n\n return consumed;\n }\n\n _onMediaInfo(mediaInfo) {\n if (this._mediaInfo == null) {\n // Store first segment's mediainfo as global mediaInfo\n this._mediaInfo = Object.assign({}, mediaInfo);\n this._mediaInfo.keyframesIndex = null;\n this._mediaInfo.segments = [];\n this._mediaInfo.segmentCount = this._mediaDataSource.segments.length;\n Object.setPrototypeOf(this._mediaInfo, MediaInfo.prototype);\n }\n\n let segmentInfo = Object.assign({}, mediaInfo);\n Object.setPrototypeOf(segmentInfo, MediaInfo.prototype);\n this._mediaInfo.segments[this._currentSegmentIndex] = segmentInfo;\n\n // notify mediaInfo update\n this._reportSegmentMediaInfo(this._currentSegmentIndex);\n\n if (this._pendingSeekTime != null) {\n Promise.resolve().then(() => {\n let target = this._pendingSeekTime;\n this._pendingSeekTime = null;\n this.seek(target);\n });\n }\n }\n\n _onIOSeeked() {\n this._remuxer.insertDiscontinuity();\n }\n\n _onIOComplete(extraData) {\n let segmentIndex = extraData;\n let nextSegmentIndex = segmentIndex + 1;\n\n if (nextSegmentIndex < this._mediaDataSource.segments.length) {\n this._internalAbort();\n this._loadSegment(nextSegmentIndex);\n } else {\n this._emitter.emit(TransmuxingEvents.LOADING_COMPLETE);\n this._disableStatisticsReporter();\n }\n }\n\n _onIORedirect(redirectedURL) {\n let segmentIndex = this._ioctl.extraData;\n this._mediaDataSource.segments[segmentIndex].redirectedURL = redirectedURL;\n }\n\n _onIORecoveredEarlyEof() {\n this._emitter.emit(TransmuxingEvents.RECOVERED_EARLY_EOF);\n }\n\n _onIOException(type, info) {\n Log.e(this.TAG, `IOException: type = ${type}, code = ${info.code}, msg = ${info.msg}`);\n this._emitter.emit(TransmuxingEvents.IO_ERROR, type, info);\n this._disableStatisticsReporter();\n }\n\n _onDemuxException(type, info) {\n Log.e(this.TAG, `DemuxException: type = ${type}, info = ${info}`);\n this._emitter.emit(TransmuxingEvents.DEMUX_ERROR, type, info);\n }\n\n _onRemuxerInitSegmentArrival(type, initSegment) {\n this._emitter.emit(TransmuxingEvents.INIT_SEGMENT, type, initSegment);\n }\n\n _onRemuxerMediaSegmentArrival(type, mediaSegment) {\n if (this._pendingSeekTime != null) {\n // Media segments after new-segment cross-seeking should be dropped.\n return;\n }\n this._emitter.emit(TransmuxingEvents.MEDIA_SEGMENT, type, mediaSegment);\n\n // Resolve pending seekPoint\n if (this._pendingResolveSeekPoint != null && type === 'video') {\n let syncPoints = mediaSegment.info.syncPoints;\n let seekpoint = this._pendingResolveSeekPoint;\n this._pendingResolveSeekPoint = null;\n\n // Safari: Pass PTS for recommend_seekpoint\n if (Browser.safari && syncPoints.length > 0 && syncPoints[0].originalDts === seekpoint) {\n seekpoint = syncPoints[0].pts;\n }\n // else: use original DTS (keyframe.milliseconds)\n\n this._emitter.emit(TransmuxingEvents.RECOMMEND_SEEKPOINT, seekpoint);\n }\n }\n\n _enableStatisticsReporter() {\n if (this._statisticsReporter == null) {\n this._statisticsReporter = self.setInterval(\n this._reportStatisticsInfo.bind(this),\n this._config.statisticsInfoReportInterval);\n }\n }\n\n _disableStatisticsReporter() {\n if (this._statisticsReporter) {\n self.clearInterval(this._statisticsReporter);\n this._statisticsReporter = null;\n }\n }\n\n _reportSegmentMediaInfo(segmentIndex) {\n let segmentInfo = this._mediaInfo.segments[segmentIndex];\n let exportInfo = Object.assign({}, segmentInfo);\n\n exportInfo.duration = this._mediaInfo.duration;\n exportInfo.segmentCount = this._mediaInfo.segmentCount;\n delete exportInfo.segments;\n delete exportInfo.keyframesIndex;\n\n this._emitter.emit(TransmuxingEvents.MEDIA_INFO, exportInfo);\n }\n\n _reportStatisticsInfo() {\n let info = {};\n\n info.url = this._ioctl.currentURL;\n info.hasRedirect = this._ioctl.hasRedirect;\n if (info.hasRedirect) {\n info.redirectedURL = this._ioctl.currentRedirectedURL;\n }\n\n info.speed = this._ioctl.currentSpeed;\n info.loaderType = this._ioctl.loaderType;\n info.currentSegmentIndex = this._currentSegmentIndex;\n info.totalSegmentCount = this._mediaDataSource.segments.length;\n\n this._emitter.emit(TransmuxingEvents.STATISTICS_INFO, info);\n }\n\n}\n\nexport default TransmuxingController;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst TransmuxingEvents = {\n IO_ERROR: 'io_error',\n DEMUX_ERROR: 'demux_error',\n INIT_SEGMENT: 'init_segment',\n MEDIA_SEGMENT: 'media_segment',\n LOADING_COMPLETE: 'loading_complete',\n RECOVERED_EARLY_EOF: 'recovered_early_eof',\n MEDIA_INFO: 'media_info',\n STATISTICS_INFO: 'statistics_info',\n RECOMMEND_SEEKPOINT: 'recommend_seekpoint'\n};\n\nexport default TransmuxingEvents;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport LoggingControl from '../utils/logging-control.js';\nimport Polyfill from '../utils/polyfill.js';\nimport TransmuxingController from './transmuxing-controller.js';\nimport TransmuxingEvents from './transmuxing-events.js';\n\n/* post message to worker:\n data: {\n cmd: string\n param: any\n }\n\n receive message from worker:\n data: {\n msg: string,\n data: any\n }\n */\n\nlet TransmuxingWorker = function (self) {\n\n let TAG = 'TransmuxingWorker';\n let controller = null;\n let logcatListener = onLogcatCallback.bind(this);\n\n Polyfill.install();\n\n self.addEventListener('message', function (e) {\n switch (e.data.cmd) {\n case 'init':\n controller = new TransmuxingController(e.data.param[0], e.data.param[1]);\n controller.on(TransmuxingEvents.IO_ERROR, onIOError.bind(this));\n controller.on(TransmuxingEvents.DEMUX_ERROR, onDemuxError.bind(this));\n controller.on(TransmuxingEvents.INIT_SEGMENT, onInitSegment.bind(this));\n controller.on(TransmuxingEvents.MEDIA_SEGMENT, onMediaSegment.bind(this));\n controller.on(TransmuxingEvents.LOADING_COMPLETE, onLoadingComplete.bind(this));\n controller.on(TransmuxingEvents.RECOVERED_EARLY_EOF, onRecoveredEarlyEof.bind(this));\n controller.on(TransmuxingEvents.MEDIA_INFO, onMediaInfo.bind(this));\n controller.on(TransmuxingEvents.STATISTICS_INFO, onStatisticsInfo.bind(this));\n controller.on(TransmuxingEvents.RECOMMEND_SEEKPOINT, onRecommendSeekpoint.bind(this));\n break;\n case 'destroy':\n if (controller) {\n controller.destroy();\n controller = null;\n }\n self.postMessage({msg: 'destroyed'});\n break;\n case 'start':\n controller.start();\n break;\n case 'stop':\n controller.stop();\n break;\n case 'seek':\n controller.seek(e.data.param);\n break;\n case 'pause':\n controller.pause();\n break;\n case 'resume':\n controller.resume();\n break;\n case 'logging_config': {\n let config = e.data.param;\n LoggingControl.applyConfig(config);\n\n if (config.enableCallback === true) {\n LoggingControl.addLogListener(logcatListener);\n } else {\n LoggingControl.removeLogListener(logcatListener);\n }\n break;\n }\n }\n });\n\n function onInitSegment(type, initSegment) {\n let obj = {\n msg: TransmuxingEvents.INIT_SEGMENT,\n data: {\n type: type,\n data: initSegment\n }\n };\n self.postMessage(obj, [initSegment.data]); // data: ArrayBuffer\n }\n\n function onMediaSegment(type, mediaSegment) {\n let obj = {\n msg: TransmuxingEvents.MEDIA_SEGMENT,\n data: {\n type: type,\n data: mediaSegment\n }\n };\n self.postMessage(obj, [mediaSegment.data]); // data: ArrayBuffer\n }\n\n function onLoadingComplete() {\n let obj = {\n msg: TransmuxingEvents.LOADING_COMPLETE\n };\n self.postMessage(obj);\n }\n\n function onRecoveredEarlyEof() {\n let obj = {\n msg: TransmuxingEvents.RECOVERED_EARLY_EOF\n };\n self.postMessage(obj);\n }\n\n function onMediaInfo(mediaInfo) {\n let obj = {\n msg: TransmuxingEvents.MEDIA_INFO,\n data: mediaInfo\n };\n self.postMessage(obj);\n }\n\n function onStatisticsInfo(statInfo) {\n let obj = {\n msg: TransmuxingEvents.STATISTICS_INFO,\n data: statInfo\n };\n self.postMessage(obj);\n }\n\n function onIOError(type, info) {\n self.postMessage({\n msg: TransmuxingEvents.IO_ERROR,\n data: {\n type: type,\n info: info\n }\n });\n }\n\n function onDemuxError(type, info) {\n self.postMessage({\n msg: TransmuxingEvents.DEMUX_ERROR,\n data: {\n type: type,\n info: info\n }\n });\n }\n\n function onRecommendSeekpoint(milliseconds) {\n self.postMessage({\n msg: TransmuxingEvents.RECOMMEND_SEEKPOINT,\n data: milliseconds\n });\n }\n\n function onLogcatCallback(type, str) {\n self.postMessage({\n msg: 'logcat_callback',\n data: {\n type: type,\n logcat: str\n }\n });\n }\n\n};\n\nexport default TransmuxingWorker;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport decodeUTF8 from '../utils/utf8-conv.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\nlet le = (function () {\n let buf = new ArrayBuffer(2);\n (new DataView(buf)).setInt16(0, 256, true); // little-endian write\n return (new Int16Array(buf))[0] === 256; // platform-spec read, if equal then LE\n})();\n\nclass AMF {\n\n static parseScriptData(arrayBuffer, dataOffset, dataSize) {\n let data = {};\n\n try {\n let name = AMF.parseValue(arrayBuffer, dataOffset, dataSize);\n let value = AMF.parseValue(arrayBuffer, dataOffset + name.size, dataSize - name.size);\n\n data[name.data] = value.data;\n } catch (e) {\n Log.e('AMF', e.toString());\n }\n\n return data;\n }\n\n static parseObject(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 3) {\n throw new IllegalStateException('Data not enough when parse ScriptDataObject');\n }\n let name = AMF.parseString(arrayBuffer, dataOffset, dataSize);\n let value = AMF.parseValue(arrayBuffer, dataOffset + name.size, dataSize - name.size);\n let isObjectEnd = value.objectEnd;\n\n return {\n data: {\n name: name.data,\n value: value.data\n },\n size: name.size + value.size,\n objectEnd: isObjectEnd\n };\n }\n\n static parseVariable(arrayBuffer, dataOffset, dataSize) {\n return AMF.parseObject(arrayBuffer, dataOffset, dataSize);\n }\n\n static parseString(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 2) {\n throw new IllegalStateException('Data not enough when parse String');\n }\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n let length = v.getUint16(0, !le);\n\n let str;\n if (length > 0) {\n str = decodeUTF8(new Uint8Array(arrayBuffer, dataOffset + 2, length));\n } else {\n str = '';\n }\n\n return {\n data: str,\n size: 2 + length\n };\n }\n\n static parseLongString(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 4) {\n throw new IllegalStateException('Data not enough when parse LongString');\n }\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n let length = v.getUint32(0, !le);\n\n let str;\n if (length > 0) {\n str = decodeUTF8(new Uint8Array(arrayBuffer, dataOffset + 4, length));\n } else {\n str = '';\n }\n\n return {\n data: str,\n size: 4 + length\n };\n }\n\n static parseDate(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 10) {\n throw new IllegalStateException('Data size invalid when parse Date');\n }\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n let timestamp = v.getFloat64(0, !le);\n let localTimeOffset = v.getInt16(8, !le);\n timestamp += localTimeOffset * 60 * 1000; // get UTC time\n\n return {\n data: new Date(timestamp),\n size: 8 + 2\n };\n }\n\n static parseValue(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 1) {\n throw new IllegalStateException('Data not enough when parse Value');\n }\n\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let offset = 1;\n let type = v.getUint8(0);\n let value;\n let objectEnd = false;\n\n try {\n switch (type) {\n case 0: // Number(Double) type\n value = v.getFloat64(1, !le);\n offset += 8;\n break;\n case 1: { // Boolean type\n let b = v.getUint8(1);\n value = b ? true : false;\n offset += 1;\n break;\n }\n case 2: { // String type\n let amfstr = AMF.parseString(arrayBuffer, dataOffset + 1, dataSize - 1);\n value = amfstr.data;\n offset += amfstr.size;\n break;\n }\n case 3: { // Object(s) type\n value = {};\n let terminal = 0; // workaround for malformed Objects which has missing ScriptDataObjectEnd\n if ((v.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {\n terminal = 3;\n }\n while (offset < dataSize - 4) { // 4 === type(UI8) + ScriptDataObjectEnd(UI24)\n let amfobj = AMF.parseObject(arrayBuffer, dataOffset + offset, dataSize - offset - terminal);\n if (amfobj.objectEnd)\n break;\n value[amfobj.data.name] = amfobj.data.value;\n offset += amfobj.size;\n }\n if (offset <= dataSize - 3) {\n let marker = v.getUint32(offset - 1, !le) & 0x00FFFFFF;\n if (marker === 9) {\n offset += 3;\n }\n }\n break;\n }\n case 8: { // ECMA array type (Mixed array)\n value = {};\n offset += 4; // ECMAArrayLength(UI32)\n let terminal = 0; // workaround for malformed MixedArrays which has missing ScriptDataObjectEnd\n if ((v.getUint32(dataSize - 4, !le) & 0x00FFFFFF) === 9) {\n terminal = 3;\n }\n while (offset < dataSize - 8) { // 8 === type(UI8) + ECMAArrayLength(UI32) + ScriptDataVariableEnd(UI24)\n let amfvar = AMF.parseVariable(arrayBuffer, dataOffset + offset, dataSize - offset - terminal);\n if (amfvar.objectEnd)\n break;\n value[amfvar.data.name] = amfvar.data.value;\n offset += amfvar.size;\n }\n if (offset <= dataSize - 3) {\n let marker = v.getUint32(offset - 1, !le) & 0x00FFFFFF;\n if (marker === 9) {\n offset += 3;\n }\n }\n break;\n }\n case 9: // ScriptDataObjectEnd\n value = undefined;\n offset = 1;\n objectEnd = true;\n break;\n case 10: { // Strict array type\n // ScriptDataValue[n]. NOTE: according to video_file_format_spec_v10_1.pdf\n value = [];\n let strictArrayLength = v.getUint32(1, !le);\n offset += 4;\n for (let i = 0; i < strictArrayLength; i++) {\n let val = AMF.parseValue(arrayBuffer, dataOffset + offset, dataSize - offset);\n value.push(val.data);\n offset += val.size;\n }\n break;\n }\n case 11: { // Date type\n let date = AMF.parseDate(arrayBuffer, dataOffset + 1, dataSize - 1);\n value = date.data;\n offset += date.size;\n break;\n }\n case 12: { // Long string type\n let amfLongStr = AMF.parseString(arrayBuffer, dataOffset + 1, dataSize - 1);\n value = amfLongStr.data;\n offset += amfLongStr.size;\n break;\n }\n default:\n // ignore and skip\n offset = dataSize;\n Log.w('AMF', 'Unsupported AMF value type ' + type);\n }\n } catch (e) {\n Log.e('AMF', e.toString());\n }\n\n return {\n data: value,\n size: offset,\n objectEnd: objectEnd\n };\n }\n\n}\n\nexport default AMF;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst DemuxErrors = {\n OK: 'OK',\n FORMAT_ERROR: 'FormatError',\n FORMAT_UNSUPPORTED: 'FormatUnsupported',\n CODEC_UNSUPPORTED: 'CodecUnsupported'\n};\n\nexport default DemuxErrors;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {IllegalStateException, InvalidArgumentException} from '../utils/exception.js';\n\n// Exponential-Golomb buffer decoder\nclass ExpGolomb {\n\n constructor(uint8array) {\n this.TAG = 'ExpGolomb';\n\n this._buffer = uint8array;\n this._buffer_index = 0;\n this._total_bytes = uint8array.byteLength;\n this._total_bits = uint8array.byteLength * 8;\n this._current_word = 0;\n this._current_word_bits_left = 0;\n }\n\n destroy() {\n this._buffer = null;\n }\n\n _fillCurrentWord() {\n let buffer_bytes_left = this._total_bytes - this._buffer_index;\n if (buffer_bytes_left <= 0)\n throw new IllegalStateException('ExpGolomb: _fillCurrentWord() but no bytes available');\n\n let bytes_read = Math.min(4, buffer_bytes_left);\n let word = new Uint8Array(4);\n word.set(this._buffer.subarray(this._buffer_index, this._buffer_index + bytes_read));\n this._current_word = new DataView(word.buffer).getUint32(0, false);\n\n this._buffer_index += bytes_read;\n this._current_word_bits_left = bytes_read * 8;\n }\n\n readBits(bits) {\n if (bits > 32)\n throw new InvalidArgumentException('ExpGolomb: readBits() bits exceeded max 32bits!');\n\n if (bits <= this._current_word_bits_left) {\n let result = this._current_word >>> (32 - bits);\n this._current_word <<= bits;\n this._current_word_bits_left -= bits;\n return result;\n }\n\n let result = this._current_word_bits_left ? this._current_word : 0;\n result = result >>> (32 - this._current_word_bits_left);\n let bits_need_left = bits - this._current_word_bits_left;\n\n this._fillCurrentWord();\n let bits_read_next = Math.min(bits_need_left, this._current_word_bits_left);\n\n let result2 = this._current_word >>> (32 - bits_read_next);\n this._current_word <<= bits_read_next;\n this._current_word_bits_left -= bits_read_next;\n\n result = (result << bits_read_next) | result2;\n return result;\n }\n\n readBool() {\n return this.readBits(1) === 1;\n }\n\n readByte() {\n return this.readBits(8);\n }\n\n _skipLeadingZero() {\n let zero_count;\n for (zero_count = 0; zero_count < this._current_word_bits_left; zero_count++) {\n if (0 !== (this._current_word & (0x80000000 >>> zero_count))) {\n this._current_word <<= zero_count;\n this._current_word_bits_left -= zero_count;\n return zero_count;\n }\n }\n this._fillCurrentWord();\n return zero_count + this._skipLeadingZero();\n }\n\n readUEG() { // unsigned exponential golomb\n let leading_zeros = this._skipLeadingZero();\n return this.readBits(leading_zeros + 1) - 1;\n }\n\n readSEG() { // signed exponential golomb\n let value = this.readUEG();\n if (value & 0x01) {\n return (value + 1) >>> 1;\n } else {\n return -1 * (value >>> 1);\n }\n }\n\n}\n\nexport default ExpGolomb;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport AMF from './amf-parser.js';\nimport SPSParser from './sps-parser.js';\nimport DemuxErrors from './demux-errors.js';\nimport MediaInfo from '../core/media-info.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\nfunction Swap16(src) {\n return (((src >>> 8) & 0xFF) |\n ((src & 0xFF) << 8));\n}\n\nfunction Swap32(src) {\n return (((src & 0xFF000000) >>> 24) |\n ((src & 0x00FF0000) >>> 8) |\n ((src & 0x0000FF00) << 8) |\n ((src & 0x000000FF) << 24));\n}\n\nfunction ReadBig32(array, index) {\n return ((array[index] << 24) |\n (array[index + 1] << 16) |\n (array[index + 2] << 8) |\n (array[index + 3]));\n}\n\n\nclass FLVDemuxer {\n\n constructor(probeData, config) {\n this.TAG = 'FLVDemuxer';\n\n this._config = config;\n\n this._onError = null;\n this._onMediaInfo = null;\n this._onTrackMetadata = null;\n this._onDataAvailable = null;\n\n this._dataOffset = probeData.dataOffset;\n this._firstParse = true;\n this._dispatch = false;\n\n this._hasAudio = probeData.hasAudioTrack;\n this._hasVideo = probeData.hasVideoTrack;\n\n this._hasAudioFlagOverrided = false;\n this._hasVideoFlagOverrided = false;\n\n this._audioInitialMetadataDispatched = false;\n this._videoInitialMetadataDispatched = false;\n\n this._mediaInfo = new MediaInfo();\n this._mediaInfo.hasAudio = this._hasAudio;\n this._mediaInfo.hasVideo = this._hasVideo;\n this._metadata = null;\n this._audioMetadata = null;\n this._videoMetadata = null;\n\n this._naluLengthSize = 4;\n this._timestampBase = 0; // int32, in milliseconds\n this._timescale = 1000;\n this._duration = 0; // int32, in milliseconds\n this._durationOverrided = false;\n this._referenceFrameRate = {\n fixed: true,\n fps: 23.976,\n fps_num: 23976,\n fps_den: 1000\n };\n\n this._flvSoundRateTable = [5500, 11025, 22050, 44100, 48000];\n\n this._mpegSamplingRates = [\n 96000, 88200, 64000, 48000, 44100, 32000,\n 24000, 22050, 16000, 12000, 11025, 8000, 7350\n ];\n\n this._mpegAudioV10SampleRateTable = [44100, 48000, 32000, 0];\n this._mpegAudioV20SampleRateTable = [22050, 24000, 16000, 0];\n this._mpegAudioV25SampleRateTable = [11025, 12000, 8000, 0];\n\n this._mpegAudioL1BitRateTable = [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1];\n this._mpegAudioL2BitRateTable = [0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1];\n this._mpegAudioL3BitRateTable = [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1];\n\n this._videoTrack = {type: 'video', id: 1, sequenceNumber: 0, samples: [], length: 0};\n this._audioTrack = {type: 'audio', id: 2, sequenceNumber: 0, samples: [], length: 0};\n\n this._littleEndian = (function () {\n let buf = new ArrayBuffer(2);\n (new DataView(buf)).setInt16(0, 256, true); // little-endian write\n return (new Int16Array(buf))[0] === 256; // platform-spec read, if equal then LE\n })();\n }\n\n destroy() {\n this._mediaInfo = null;\n this._metadata = null;\n this._audioMetadata = null;\n this._videoMetadata = null;\n this._videoTrack = null;\n this._audioTrack = null;\n\n this._onError = null;\n this._onMediaInfo = null;\n this._onTrackMetadata = null;\n this._onDataAvailable = null;\n }\n\n static probe(buffer) {\n let data = new Uint8Array(buffer);\n let mismatch = {match: false};\n\n if (data[0] !== 0x46 || data[1] !== 0x4C || data[2] !== 0x56 || data[3] !== 0x01) {\n return mismatch;\n }\n\n let hasAudio = ((data[4] & 4) >>> 2) !== 0;\n let hasVideo = (data[4] & 1) !== 0;\n\n let offset = ReadBig32(data, 5);\n\n if (offset < 9) {\n return mismatch;\n }\n\n return {\n match: true,\n consumed: offset,\n dataOffset: offset,\n hasAudioTrack: hasAudio,\n hasVideoTrack: hasVideo\n };\n }\n\n bindDataSource(loader) {\n loader.onDataArrival = this.parseChunks.bind(this);\n return this;\n }\n\n // prototype: function(type: string, metadata: any): void\n get onTrackMetadata() {\n return this._onTrackMetadata;\n }\n\n set onTrackMetadata(callback) {\n this._onTrackMetadata = callback;\n }\n\n // prototype: function(mediaInfo: MediaInfo): void\n get onMediaInfo() {\n return this._onMediaInfo;\n }\n\n set onMediaInfo(callback) {\n this._onMediaInfo = callback;\n }\n\n // prototype: function(type: number, info: string): void\n get onError() {\n return this._onError;\n }\n\n set onError(callback) {\n this._onError = callback;\n }\n\n // prototype: function(videoTrack: any, audioTrack: any): void\n get onDataAvailable() {\n return this._onDataAvailable;\n }\n\n set onDataAvailable(callback) {\n this._onDataAvailable = callback;\n }\n\n // timestamp base for output samples, must be in milliseconds\n get timestampBase() {\n return this._timestampBase;\n }\n\n set timestampBase(base) {\n this._timestampBase = base;\n }\n\n get overridedDuration() {\n return this._duration;\n }\n\n // Force-override media duration. Must be in milliseconds, int32\n set overridedDuration(duration) {\n this._durationOverrided = true;\n this._duration = duration;\n this._mediaInfo.duration = duration;\n }\n\n // Force-override audio track present flag, boolean\n set overridedHasAudio(hasAudio) {\n this._hasAudioFlagOverrided = true;\n this._hasAudio = hasAudio;\n this._mediaInfo.hasAudio = hasAudio;\n }\n\n // Force-override video track present flag, boolean\n set overridedHasVideo(hasVideo) {\n this._hasVideoFlagOverrided = true;\n this._hasVideo = hasVideo;\n this._mediaInfo.hasVideo = hasVideo;\n }\n\n resetMediaInfo() {\n this._mediaInfo = new MediaInfo();\n }\n\n _isInitialMetadataDispatched() {\n if (this._hasAudio && this._hasVideo) { // both audio & video\n return this._audioInitialMetadataDispatched && this._videoInitialMetadataDispatched;\n }\n if (this._hasAudio && !this._hasVideo) { // audio only\n return this._audioInitialMetadataDispatched;\n }\n if (!this._hasAudio && this._hasVideo) { // video only\n return this._videoInitialMetadataDispatched;\n }\n return false;\n }\n\n // function parseChunks(chunk: ArrayBuffer, byteStart: number): number;\n parseChunks(chunk, byteStart) {\n if (!this._onError || !this._onMediaInfo || !this._onTrackMetadata || !this._onDataAvailable) {\n throw new IllegalStateException('Flv: onError & onMediaInfo & onTrackMetadata & onDataAvailable callback must be specified');\n }\n\n let offset = 0;\n let le = this._littleEndian;\n\n if (byteStart === 0) { // buffer with FLV header\n if (chunk.byteLength > 13) {\n let probeData = FLVDemuxer.probe(chunk);\n offset = probeData.dataOffset;\n } else {\n return 0;\n }\n }\n\n if (this._firstParse) { // handle PreviousTagSize0 before Tag1\n this._firstParse = false;\n if (byteStart + offset !== this._dataOffset) {\n Log.w(this.TAG, 'First time parsing but chunk byteStart invalid!');\n }\n\n let v = new DataView(chunk, offset);\n let prevTagSize0 = v.getUint32(0, !le);\n if (prevTagSize0 !== 0) {\n Log.w(this.TAG, 'PrevTagSize0 !== 0 !!!');\n }\n offset += 4;\n }\n\n while (offset < chunk.byteLength) {\n this._dispatch = true;\n\n let v = new DataView(chunk, offset);\n\n if (offset + 11 + 4 > chunk.byteLength) {\n // data not enough for parsing an flv tag\n break;\n }\n\n let tagType = v.getUint8(0);\n let dataSize = v.getUint32(0, !le) & 0x00FFFFFF;\n\n if (offset + 11 + dataSize + 4 > chunk.byteLength) {\n // data not enough for parsing actual data body\n break;\n }\n\n if (tagType !== 8 && tagType !== 9 && tagType !== 18) {\n Log.w(this.TAG, `Unsupported tag type ${tagType}, skipped`);\n // consume the whole tag (skip it)\n offset += 11 + dataSize + 4;\n continue;\n }\n\n let ts2 = v.getUint8(4);\n let ts1 = v.getUint8(5);\n let ts0 = v.getUint8(6);\n let ts3 = v.getUint8(7);\n\n let timestamp = ts0 | (ts1 << 8) | (ts2 << 16) | (ts3 << 24);\n\n let streamId = v.getUint32(7, !le) & 0x00FFFFFF;\n if (streamId !== 0) {\n Log.w(this.TAG, 'Meet tag which has StreamID != 0!');\n }\n\n let dataOffset = offset + 11;\n\n switch (tagType) {\n case 8: // Audio\n this._parseAudioData(chunk, dataOffset, dataSize, timestamp);\n break;\n case 9: // Video\n this._parseVideoData(chunk, dataOffset, dataSize, timestamp, byteStart + offset);\n break;\n case 18: // ScriptDataObject\n this._parseScriptData(chunk, dataOffset, dataSize);\n break;\n }\n\n let prevTagSize = v.getUint32(11 + dataSize, !le);\n if (prevTagSize !== 11 + dataSize) {\n Log.w(this.TAG, `Invalid PrevTagSize ${prevTagSize}`);\n }\n\n offset += 11 + dataSize + 4; // tagBody + dataSize + prevTagSize\n }\n\n // dispatch parsed frames to consumer (typically, the remuxer)\n if (this._isInitialMetadataDispatched()) {\n if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {\n this._onDataAvailable(this._audioTrack, this._videoTrack);\n }\n }\n\n return offset; // consumed bytes, just equals latest offset index\n }\n\n _parseScriptData(arrayBuffer, dataOffset, dataSize) {\n let scriptData = AMF.parseScriptData(arrayBuffer, dataOffset, dataSize);\n\n if (scriptData.hasOwnProperty('onMetaData')) {\n if (scriptData.onMetaData == null || typeof scriptData.onMetaData !== 'object') {\n Log.w(this.TAG, 'Invalid onMetaData structure!');\n return;\n }\n if (this._metadata) {\n Log.w(this.TAG, 'Found another onMetaData tag!');\n }\n this._metadata = scriptData;\n let onMetaData = this._metadata.onMetaData;\n\n if (typeof onMetaData.hasAudio === 'boolean') { // hasAudio\n if (this._hasAudioFlagOverrided === false) {\n this._hasAudio = onMetaData.hasAudio;\n this._mediaInfo.hasAudio = this._hasAudio;\n }\n }\n if (typeof onMetaData.hasVideo === 'boolean') { // hasVideo\n if (this._hasVideoFlagOverrided === false) {\n this._hasVideo = onMetaData.hasVideo;\n this._mediaInfo.hasVideo = this._hasVideo;\n }\n }\n if (typeof onMetaData.audiodatarate === 'number') { // audiodatarate\n this._mediaInfo.audioDataRate = onMetaData.audiodatarate;\n }\n if (typeof onMetaData.videodatarate === 'number') { // videodatarate\n this._mediaInfo.videoDataRate = onMetaData.videodatarate;\n }\n if (typeof onMetaData.width === 'number') { // width\n this._mediaInfo.width = onMetaData.width;\n }\n if (typeof onMetaData.height === 'number') { // height\n this._mediaInfo.height = onMetaData.height;\n }\n if (typeof onMetaData.duration === 'number') { // duration\n if (!this._durationOverrided) {\n let duration = Math.floor(onMetaData.duration * this._timescale);\n this._duration = duration;\n this._mediaInfo.duration = duration;\n }\n } else {\n this._mediaInfo.duration = 0;\n }\n if (typeof onMetaData.framerate === 'number') { // framerate\n let fps_num = Math.floor(onMetaData.framerate * 1000);\n if (fps_num > 0) {\n let fps = fps_num / 1000;\n this._referenceFrameRate.fixed = true;\n this._referenceFrameRate.fps = fps;\n this._referenceFrameRate.fps_num = fps_num;\n this._referenceFrameRate.fps_den = 1000;\n this._mediaInfo.fps = fps;\n }\n }\n if (typeof onMetaData.keyframes === 'object') { // keyframes\n this._mediaInfo.hasKeyframesIndex = true;\n let keyframes = onMetaData.keyframes;\n this._mediaInfo.keyframesIndex = this._parseKeyframesIndex(keyframes);\n onMetaData.keyframes = null; // keyframes has been extracted, remove it\n } else {\n this._mediaInfo.hasKeyframesIndex = false;\n }\n this._dispatch = false;\n this._mediaInfo.metadata = onMetaData;\n Log.v(this.TAG, 'Parsed onMetaData');\n if (this._mediaInfo.isComplete()) {\n this._onMediaInfo(this._mediaInfo);\n }\n }\n }\n\n _parseKeyframesIndex(keyframes) {\n let times = [];\n let filepositions = [];\n\n // ignore first keyframe which is actually AVC Sequence Header (AVCDecoderConfigurationRecord)\n for (let i = 1; i < keyframes.times.length; i++) {\n let time = this._timestampBase + Math.floor(keyframes.times[i] * 1000);\n times.push(time);\n filepositions.push(keyframes.filepositions[i]);\n }\n\n return {\n times: times,\n filepositions: filepositions\n };\n }\n\n _parseAudioData(arrayBuffer, dataOffset, dataSize, tagTimestamp) {\n if (dataSize <= 1) {\n Log.w(this.TAG, 'Flv: Invalid audio packet, missing SoundData payload!');\n return;\n }\n\n if (this._hasAudioFlagOverrided === true && this._hasAudio === false) {\n // If hasAudio: false indicated explicitly in MediaDataSource,\n // Ignore all the audio packets\n return;\n }\n\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let soundSpec = v.getUint8(0);\n\n let soundFormat = soundSpec >>> 4;\n if (soundFormat !== 2 && soundFormat !== 10) { // MP3 or AAC\n this._onError(DemuxErrors.CODEC_UNSUPPORTED, 'Flv: Unsupported audio codec idx: ' + soundFormat);\n return;\n }\n\n let soundRate = 0;\n let soundRateIndex = (soundSpec & 12) >>> 2;\n if (soundRateIndex >= 0 && soundRateIndex <= 4) {\n soundRate = this._flvSoundRateTable[soundRateIndex];\n } else {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid audio sample rate idx: ' + soundRateIndex);\n return;\n }\n\n let soundSize = (soundSpec & 2) >>> 1; // unused\n let soundType = (soundSpec & 1);\n\n\n let meta = this._audioMetadata;\n let track = this._audioTrack;\n\n if (!meta) {\n if (this._hasAudio === false && this._hasAudioFlagOverrided === false) {\n this._hasAudio = true;\n this._mediaInfo.hasAudio = true;\n }\n\n // initial metadata\n meta = this._audioMetadata = {};\n meta.type = 'audio';\n meta.id = track.id;\n meta.timescale = this._timescale;\n meta.duration = this._duration;\n meta.audioSampleRate = soundRate;\n meta.channelCount = (soundType === 0 ? 1 : 2);\n }\n\n if (soundFormat === 10) { // AAC\n let aacData = this._parseAACAudioData(arrayBuffer, dataOffset + 1, dataSize - 1);\n if (aacData == undefined) {\n return;\n }\n\n if (aacData.packetType === 0) { // AAC sequence header (AudioSpecificConfig)\n if (meta.config) {\n Log.w(this.TAG, 'Found another AudioSpecificConfig!');\n }\n let misc = aacData.data;\n meta.audioSampleRate = misc.samplingRate;\n meta.channelCount = misc.channelCount;\n meta.codec = misc.codec;\n meta.originalCodec = misc.originalCodec;\n meta.config = misc.config;\n // The decode result of an aac sample is 1024 PCM samples\n meta.refSampleDuration = 1024 / meta.audioSampleRate * meta.timescale;\n Log.v(this.TAG, 'Parsed AudioSpecificConfig');\n\n if (this._isInitialMetadataDispatched()) {\n // Non-initial metadata, force dispatch (or flush) parsed frames to remuxer\n if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {\n this._onDataAvailable(this._audioTrack, this._videoTrack);\n }\n } else {\n this._audioInitialMetadataDispatched = true;\n }\n // then notify new metadata\n this._dispatch = false;\n this._onTrackMetadata('audio', meta);\n\n let mi = this._mediaInfo;\n mi.audioCodec = meta.originalCodec;\n mi.audioSampleRate = meta.audioSampleRate;\n mi.audioChannelCount = meta.channelCount;\n if (mi.hasVideo) {\n if (mi.videoCodec != null) {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + ',' + mi.audioCodec + '\"';\n }\n } else {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.audioCodec + '\"';\n }\n if (mi.isComplete()) {\n this._onMediaInfo(mi);\n }\n } else if (aacData.packetType === 1) { // AAC raw frame data\n let dts = this._timestampBase + tagTimestamp;\n let aacSample = {unit: aacData.data, dts: dts, pts: dts};\n track.samples.push(aacSample);\n track.length += aacData.data.length;\n } else {\n Log.e(this.TAG, `Flv: Unsupported AAC data type ${aacData.packetType}`);\n }\n } else if (soundFormat === 2) { // MP3\n if (!meta.codec) {\n // We need metadata for mp3 audio track, extract info from frame header\n let misc = this._parseMP3AudioData(arrayBuffer, dataOffset + 1, dataSize - 1, true);\n if (misc == undefined) {\n return;\n }\n meta.audioSampleRate = misc.samplingRate;\n meta.channelCount = misc.channelCount;\n meta.codec = misc.codec;\n meta.originalCodec = misc.originalCodec;\n // The decode result of an mp3 sample is 1152 PCM samples\n meta.refSampleDuration = 1152 / meta.audioSampleRate * meta.timescale;\n Log.v(this.TAG, 'Parsed MPEG Audio Frame Header');\n\n this._audioInitialMetadataDispatched = true;\n this._onTrackMetadata('audio', meta);\n\n let mi = this._mediaInfo;\n mi.audioCodec = meta.codec;\n mi.audioSampleRate = meta.audioSampleRate;\n mi.audioChannelCount = meta.channelCount;\n mi.audioDataRate = misc.bitRate;\n if (mi.hasVideo) {\n if (mi.videoCodec != null) {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + ',' + mi.audioCodec + '\"';\n }\n } else {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.audioCodec + '\"';\n }\n if (mi.isComplete()) {\n this._onMediaInfo(mi);\n }\n }\n\n // This packet is always a valid audio packet, extract it\n let data = this._parseMP3AudioData(arrayBuffer, dataOffset + 1, dataSize - 1, false);\n if (data == undefined) {\n return;\n }\n let dts = this._timestampBase + tagTimestamp;\n let mp3Sample = {unit: data, dts: dts, pts: dts};\n track.samples.push(mp3Sample);\n track.length += data.length;\n }\n }\n\n _parseAACAudioData(arrayBuffer, dataOffset, dataSize) {\n if (dataSize <= 1) {\n Log.w(this.TAG, 'Flv: Invalid AAC packet, missing AACPacketType or/and Data!');\n return;\n }\n\n let result = {};\n let array = new Uint8Array(arrayBuffer, dataOffset, dataSize);\n\n result.packetType = array[0];\n\n if (array[0] === 0) {\n result.data = this._parseAACAudioSpecificConfig(arrayBuffer, dataOffset + 1, dataSize - 1);\n } else {\n result.data = array.subarray(1);\n }\n\n return result;\n }\n\n _parseAACAudioSpecificConfig(arrayBuffer, dataOffset, dataSize) {\n let array = new Uint8Array(arrayBuffer, dataOffset, dataSize);\n let config = null;\n\n /* Audio Object Type:\n 0: Null\n 1: AAC Main\n 2: AAC LC\n 3: AAC SSR (Scalable Sample Rate)\n 4: AAC LTP (Long Term Prediction)\n 5: HE-AAC / SBR (Spectral Band Replication)\n 6: AAC Scalable\n */\n\n let audioObjectType = 0;\n let originalAudioObjectType = 0;\n let audioExtensionObjectType = null;\n let samplingIndex = 0;\n let extensionSamplingIndex = null;\n\n // 5 bits\n audioObjectType = originalAudioObjectType = array[0] >>> 3;\n // 4 bits\n samplingIndex = ((array[0] & 0x07) << 1) | (array[1] >>> 7);\n if (samplingIndex < 0 || samplingIndex >= this._mpegSamplingRates.length) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: AAC invalid sampling frequency index!');\n return;\n }\n\n let samplingFrequence = this._mpegSamplingRates[samplingIndex];\n\n // 4 bits\n let channelConfig = (array[1] & 0x78) >>> 3;\n if (channelConfig < 0 || channelConfig >= 8) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: AAC invalid channel configuration');\n return;\n }\n\n if (audioObjectType === 5) { // HE-AAC?\n // 4 bits\n extensionSamplingIndex = ((array[1] & 0x07) << 1) | (array[2] >>> 7);\n // 5 bits\n audioExtensionObjectType = (array[2] & 0x7C) >>> 2;\n }\n\n // workarounds for various browsers\n let userAgent = self.navigator.userAgent.toLowerCase();\n\n if (userAgent.indexOf('firefox') !== -1) {\n // firefox: use SBR (HE-AAC) if freq less than 24kHz\n if (samplingIndex >= 6) {\n audioObjectType = 5;\n config = new Array(4);\n extensionSamplingIndex = samplingIndex - 3;\n } else { // use LC-AAC\n audioObjectType = 2;\n config = new Array(2);\n extensionSamplingIndex = samplingIndex;\n }\n } else if (userAgent.indexOf('android') !== -1) {\n // android: always use LC-AAC\n audioObjectType = 2;\n config = new Array(2);\n extensionSamplingIndex = samplingIndex;\n } else {\n // for other browsers, e.g. chrome...\n // Always use HE-AAC to make it easier to switch aac codec profile\n audioObjectType = 5;\n extensionSamplingIndex = samplingIndex;\n config = new Array(4);\n\n if (samplingIndex >= 6) {\n extensionSamplingIndex = samplingIndex - 3;\n } else if (channelConfig === 1) { // Mono channel\n audioObjectType = 2;\n config = new Array(2);\n extensionSamplingIndex = samplingIndex;\n }\n }\n\n config[0] = audioObjectType << 3;\n config[0] |= (samplingIndex & 0x0F) >>> 1;\n config[1] = (samplingIndex & 0x0F) << 7;\n config[1] |= (channelConfig & 0x0F) << 3;\n if (audioObjectType === 5) {\n config[1] |= ((extensionSamplingIndex & 0x0F) >>> 1);\n config[2] = (extensionSamplingIndex & 0x01) << 7;\n // extended audio object type: force to 2 (LC-AAC)\n config[2] |= (2 << 2);\n config[3] = 0;\n }\n\n return {\n config: config,\n samplingRate: samplingFrequence,\n channelCount: channelConfig,\n codec: 'mp4a.40.' + audioObjectType,\n originalCodec: 'mp4a.40.' + originalAudioObjectType\n };\n }\n\n _parseMP3AudioData(arrayBuffer, dataOffset, dataSize, requestHeader) {\n if (dataSize < 4) {\n Log.w(this.TAG, 'Flv: Invalid MP3 packet, header missing!');\n return;\n }\n\n let le = this._littleEndian;\n let array = new Uint8Array(arrayBuffer, dataOffset, dataSize);\n let result = null;\n\n if (requestHeader) {\n if (array[0] !== 0xFF) {\n return;\n }\n let ver = (array[1] >>> 3) & 0x03;\n let layer = (array[1] & 0x06) >> 1;\n\n let bitrate_index = (array[2] & 0xF0) >>> 4;\n let sampling_freq_index = (array[2] & 0x0C) >>> 2;\n\n let channel_mode = (array[3] >>> 6) & 0x03;\n let channel_count = channel_mode !== 3 ? 2 : 1;\n\n let sample_rate = 0;\n let bit_rate = 0;\n let object_type = 34; // Layer-3, listed in MPEG-4 Audio Object Types\n\n let codec = 'mp3';\n\n switch (ver) {\n case 0: // MPEG 2.5\n sample_rate = this._mpegAudioV25SampleRateTable[sampling_freq_index];\n break;\n case 2: // MPEG 2\n sample_rate = this._mpegAudioV20SampleRateTable[sampling_freq_index];\n break;\n case 3: // MPEG 1\n sample_rate = this._mpegAudioV10SampleRateTable[sampling_freq_index];\n break;\n }\n\n switch (layer) {\n case 1: // Layer 3\n object_type = 34;\n if (bitrate_index < this._mpegAudioL3BitRateTable.length) {\n bit_rate = this._mpegAudioL3BitRateTable[bitrate_index];\n }\n break;\n case 2: // Layer 2\n object_type = 33;\n if (bitrate_index < this._mpegAudioL2BitRateTable.length) {\n bit_rate = this._mpegAudioL2BitRateTable[bitrate_index];\n }\n break;\n case 3: // Layer 1\n object_type = 32;\n if (bitrate_index < this._mpegAudioL1BitRateTable.length) {\n bit_rate = this._mpegAudioL1BitRateTable[bitrate_index];\n }\n break;\n }\n\n result = {\n bitRate: bit_rate,\n samplingRate: sample_rate,\n channelCount: channel_count,\n codec: codec,\n originalCodec: codec\n };\n } else {\n result = array;\n }\n\n return result;\n }\n\n _parseVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition) {\n if (dataSize <= 1) {\n Log.w(this.TAG, 'Flv: Invalid video packet, missing VideoData payload!');\n return;\n }\n\n if (this._hasVideoFlagOverrided === true && this._hasVideo === false) {\n // If hasVideo: false indicated explicitly in MediaDataSource,\n // Ignore all the video packets\n return;\n }\n\n let spec = (new Uint8Array(arrayBuffer, dataOffset, dataSize))[0];\n\n let frameType = (spec & 240) >>> 4;\n let codecId = spec & 15;\n\n if (codecId !== 7) {\n this._onError(DemuxErrors.CODEC_UNSUPPORTED, `Flv: Unsupported codec in video frame: ${codecId}`);\n return;\n }\n\n this._parseAVCVideoPacket(arrayBuffer, dataOffset + 1, dataSize - 1, tagTimestamp, tagPosition, frameType);\n }\n\n _parseAVCVideoPacket(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType) {\n if (dataSize < 4) {\n Log.w(this.TAG, 'Flv: Invalid AVC packet, missing AVCPacketType or/and CompositionTime');\n return;\n }\n\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let packetType = v.getUint8(0);\n let cts = v.getUint32(0, !le) & 0x00FFFFFF;\n\n if (packetType === 0) { // AVCDecoderConfigurationRecord\n this._parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset + 4, dataSize - 4);\n } else if (packetType === 1) { // One or more Nalus\n this._parseAVCVideoData(arrayBuffer, dataOffset + 4, dataSize - 4, tagTimestamp, tagPosition, frameType, cts);\n } else if (packetType === 2) {\n // empty, AVC end of sequence\n } else {\n this._onError(DemuxErrors.FORMAT_ERROR, `Flv: Invalid video packet type ${packetType}`);\n return;\n }\n }\n\n _parseAVCDecoderConfigurationRecord(arrayBuffer, dataOffset, dataSize) {\n if (dataSize < 7) {\n Log.w(this.TAG, 'Flv: Invalid AVCDecoderConfigurationRecord, lack of data!');\n return;\n }\n\n let meta = this._videoMetadata;\n let track = this._videoTrack;\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n if (!meta) {\n if (this._hasVideo === false && this._hasVideoFlagOverrided === false) {\n this._hasVideo = true;\n this._mediaInfo.hasVideo = true;\n }\n\n meta = this._videoMetadata = {};\n meta.type = 'video';\n meta.id = track.id;\n meta.timescale = this._timescale;\n meta.duration = this._duration;\n } else {\n if (typeof meta.avcc !== 'undefined') {\n Log.w(this.TAG, 'Found another AVCDecoderConfigurationRecord!');\n }\n }\n\n let version = v.getUint8(0); // configurationVersion\n let avcProfile = v.getUint8(1); // avcProfileIndication\n let profileCompatibility = v.getUint8(2); // profile_compatibility\n let avcLevel = v.getUint8(3); // AVCLevelIndication\n\n if (version !== 1 || avcProfile === 0) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord');\n return;\n }\n\n this._naluLengthSize = (v.getUint8(4) & 3) + 1; // lengthSizeMinusOne\n if (this._naluLengthSize !== 3 && this._naluLengthSize !== 4) { // holy shit!!!\n this._onError(DemuxErrors.FORMAT_ERROR, `Flv: Strange NaluLengthSizeMinusOne: ${this._naluLengthSize - 1}`);\n return;\n }\n\n let spsCount = v.getUint8(5) & 31; // numOfSequenceParameterSets\n if (spsCount === 0) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord: No SPS');\n return;\n } else if (spsCount > 1) {\n Log.w(this.TAG, `Flv: Strange AVCDecoderConfigurationRecord: SPS Count = ${spsCount}`);\n }\n\n let offset = 6;\n\n for (let i = 0; i < spsCount; i++) {\n let len = v.getUint16(offset, !le); // sequenceParameterSetLength\n offset += 2;\n\n if (len === 0) {\n continue;\n }\n\n // Notice: Nalu without startcode header (00 00 00 01)\n let sps = new Uint8Array(arrayBuffer, dataOffset + offset, len);\n offset += len;\n\n let config = SPSParser.parseSPS(sps);\n if (i !== 0) {\n // ignore other sps's config\n continue;\n }\n\n meta.codecWidth = config.codec_size.width;\n meta.codecHeight = config.codec_size.height;\n meta.presentWidth = config.present_size.width;\n meta.presentHeight = config.present_size.height;\n\n meta.profile = config.profile_string;\n meta.level = config.level_string;\n meta.bitDepth = config.bit_depth;\n meta.chromaFormat = config.chroma_format;\n meta.sarRatio = config.sar_ratio;\n meta.frameRate = config.frame_rate;\n\n if (config.frame_rate.fixed === false ||\n config.frame_rate.fps_num === 0 ||\n config.frame_rate.fps_den === 0) {\n meta.frameRate = this._referenceFrameRate;\n }\n\n let fps_den = meta.frameRate.fps_den;\n let fps_num = meta.frameRate.fps_num;\n meta.refSampleDuration = meta.timescale * (fps_den / fps_num);\n\n let codecArray = sps.subarray(1, 4);\n let codecString = 'avc1.';\n for (let j = 0; j < 3; j++) {\n let h = codecArray[j].toString(16);\n if (h.length < 2) {\n h = '0' + h;\n }\n codecString += h;\n }\n meta.codec = codecString;\n\n let mi = this._mediaInfo;\n mi.width = meta.codecWidth;\n mi.height = meta.codecHeight;\n mi.fps = meta.frameRate.fps;\n mi.profile = meta.profile;\n mi.level = meta.level;\n mi.chromaFormat = config.chroma_format_string;\n mi.sarNum = meta.sarRatio.width;\n mi.sarDen = meta.sarRatio.height;\n mi.videoCodec = codecString;\n\n if (mi.hasAudio) {\n if (mi.audioCodec != null) {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + ',' + mi.audioCodec + '\"';\n }\n } else {\n mi.mimeType = 'video/x-flv; codecs=\"' + mi.videoCodec + '\"';\n }\n if (mi.isComplete()) {\n this._onMediaInfo(mi);\n }\n }\n\n let ppsCount = v.getUint8(offset); // numOfPictureParameterSets\n if (ppsCount === 0) {\n this._onError(DemuxErrors.FORMAT_ERROR, 'Flv: Invalid AVCDecoderConfigurationRecord: No PPS');\n return;\n } else if (ppsCount > 1) {\n Log.w(this.TAG, `Flv: Strange AVCDecoderConfigurationRecord: PPS Count = ${ppsCount}`);\n }\n\n offset++;\n\n for (let i = 0; i < ppsCount; i++) {\n let len = v.getUint16(offset, !le); // pictureParameterSetLength\n offset += 2;\n\n if (len === 0) {\n continue;\n }\n\n // pps is useless for extracting video information\n offset += len;\n }\n\n meta.avcc = new Uint8Array(dataSize);\n meta.avcc.set(new Uint8Array(arrayBuffer, dataOffset, dataSize), 0);\n Log.v(this.TAG, 'Parsed AVCDecoderConfigurationRecord');\n\n if (this._isInitialMetadataDispatched()) {\n // flush parsed frames\n if (this._dispatch && (this._audioTrack.length || this._videoTrack.length)) {\n this._onDataAvailable(this._audioTrack, this._videoTrack);\n }\n } else {\n this._videoInitialMetadataDispatched = true;\n }\n // notify new metadata\n this._dispatch = false;\n this._onTrackMetadata('video', meta);\n }\n\n _parseAVCVideoData(arrayBuffer, dataOffset, dataSize, tagTimestamp, tagPosition, frameType, cts) {\n let le = this._littleEndian;\n let v = new DataView(arrayBuffer, dataOffset, dataSize);\n\n let units = [], length = 0;\n\n let offset = 0;\n const lengthSize = this._naluLengthSize;\n let dts = this._timestampBase + tagTimestamp;\n let keyframe = (frameType === 1); // from FLV Frame Type constants\n\n while (offset < dataSize) {\n if (offset + 4 >= dataSize) {\n Log.w(this.TAG, `Malformed Nalu near timestamp ${dts}, offset = ${offset}, dataSize = ${dataSize}`);\n break; // data not enough for next Nalu\n }\n // Nalu with length-header (AVC1)\n let naluSize = v.getUint32(offset, !le); // Big-Endian read\n if (lengthSize === 3) {\n naluSize >>>= 8;\n }\n if (naluSize > dataSize - lengthSize) {\n Log.w(this.TAG, `Malformed Nalus near timestamp ${dts}, NaluSize > DataSize!`);\n return;\n }\n\n let unitType = v.getUint8(offset + lengthSize) & 0x1F;\n\n if (unitType === 5) { // IDR\n keyframe = true;\n }\n\n let data = new Uint8Array(arrayBuffer, dataOffset + offset, lengthSize + naluSize);\n let unit = {type: unitType, data: data};\n units.push(unit);\n length += data.byteLength;\n\n offset += lengthSize + naluSize;\n }\n\n if (units.length) {\n let track = this._videoTrack;\n let avcSample = {\n units: units,\n length: length,\n isKeyframe: keyframe,\n dts: dts,\n cts: cts,\n pts: (dts + cts)\n };\n if (keyframe) {\n avcSample.fileposition = tagPosition;\n }\n track.samples.push(avcSample);\n track.length += length;\n }\n }\n\n}\n\nexport default FLVDemuxer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport ExpGolomb from './exp-golomb.js';\n\nclass SPSParser {\n\n static _ebsp2rbsp(uint8array) {\n let src = uint8array;\n let src_length = src.byteLength;\n let dst = new Uint8Array(src_length);\n let dst_idx = 0;\n\n for (let i = 0; i < src_length; i++) {\n if (i >= 2) {\n // Unescape: Skip 0x03 after 00 00\n if (src[i] === 0x03 && src[i - 1] === 0x00 && src[i - 2] === 0x00) {\n continue;\n }\n }\n dst[dst_idx] = src[i];\n dst_idx++;\n }\n\n return new Uint8Array(dst.buffer, 0, dst_idx);\n }\n\n static parseSPS(uint8array) {\n let rbsp = SPSParser._ebsp2rbsp(uint8array);\n let gb = new ExpGolomb(rbsp);\n\n gb.readByte();\n let profile_idc = gb.readByte(); // profile_idc\n gb.readByte(); // constraint_set_flags[5] + reserved_zero[3]\n let level_idc = gb.readByte(); // level_idc\n gb.readUEG(); // seq_parameter_set_id\n\n let profile_string = SPSParser.getProfileString(profile_idc);\n let level_string = SPSParser.getLevelString(level_idc);\n let chroma_format_idc = 1;\n let chroma_format = 420;\n let chroma_format_table = [0, 420, 422, 444];\n let bit_depth = 8;\n\n if (profile_idc === 100 || profile_idc === 110 || profile_idc === 122 ||\n profile_idc === 244 || profile_idc === 44 || profile_idc === 83 ||\n profile_idc === 86 || profile_idc === 118 || profile_idc === 128 ||\n profile_idc === 138 || profile_idc === 144) {\n\n chroma_format_idc = gb.readUEG();\n if (chroma_format_idc === 3) {\n gb.readBits(1); // separate_colour_plane_flag\n }\n if (chroma_format_idc <= 3) {\n chroma_format = chroma_format_table[chroma_format_idc];\n }\n\n bit_depth = gb.readUEG() + 8; // bit_depth_luma_minus8\n gb.readUEG(); // bit_depth_chroma_minus8\n gb.readBits(1); // qpprime_y_zero_transform_bypass_flag\n if (gb.readBool()) { // seq_scaling_matrix_present_flag\n let scaling_list_count = (chroma_format_idc !== 3) ? 8 : 12;\n for (let i = 0; i < scaling_list_count; i++) {\n if (gb.readBool()) { // seq_scaling_list_present_flag\n if (i < 6) {\n SPSParser._skipScalingList(gb, 16);\n } else {\n SPSParser._skipScalingList(gb, 64);\n }\n }\n }\n }\n }\n gb.readUEG(); // log2_max_frame_num_minus4\n let pic_order_cnt_type = gb.readUEG();\n if (pic_order_cnt_type === 0) {\n gb.readUEG(); // log2_max_pic_order_cnt_lsb_minus_4\n } else if (pic_order_cnt_type === 1) {\n gb.readBits(1); // delta_pic_order_always_zero_flag\n gb.readSEG(); // offset_for_non_ref_pic\n gb.readSEG(); // offset_for_top_to_bottom_field\n let num_ref_frames_in_pic_order_cnt_cycle = gb.readUEG();\n for (let i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) {\n gb.readSEG(); // offset_for_ref_frame\n }\n }\n gb.readUEG(); // max_num_ref_frames\n gb.readBits(1); // gaps_in_frame_num_value_allowed_flag\n\n let pic_width_in_mbs_minus1 = gb.readUEG();\n let pic_height_in_map_units_minus1 = gb.readUEG();\n\n let frame_mbs_only_flag = gb.readBits(1);\n if (frame_mbs_only_flag === 0) {\n gb.readBits(1); // mb_adaptive_frame_field_flag\n }\n gb.readBits(1); // direct_8x8_inference_flag\n\n let frame_crop_left_offset = 0;\n let frame_crop_right_offset = 0;\n let frame_crop_top_offset = 0;\n let frame_crop_bottom_offset = 0;\n\n let frame_cropping_flag = gb.readBool();\n if (frame_cropping_flag) {\n frame_crop_left_offset = gb.readUEG();\n frame_crop_right_offset = gb.readUEG();\n frame_crop_top_offset = gb.readUEG();\n frame_crop_bottom_offset = gb.readUEG();\n }\n\n let sar_width = 1, sar_height = 1;\n let fps = 0, fps_fixed = true, fps_num = 0, fps_den = 0;\n\n let vui_parameters_present_flag = gb.readBool();\n if (vui_parameters_present_flag) {\n if (gb.readBool()) { // aspect_ratio_info_present_flag\n let aspect_ratio_idc = gb.readByte();\n let sar_w_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2];\n let sar_h_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1];\n\n if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {\n sar_width = sar_w_table[aspect_ratio_idc - 1];\n sar_height = sar_h_table[aspect_ratio_idc - 1];\n } else if (aspect_ratio_idc === 255) {\n sar_width = gb.readByte() << 8 | gb.readByte();\n sar_height = gb.readByte() << 8 | gb.readByte();\n }\n }\n\n if (gb.readBool()) { // overscan_info_present_flag\n gb.readBool(); // overscan_appropriate_flag\n }\n if (gb.readBool()) { // video_signal_type_present_flag\n gb.readBits(4); // video_format & video_full_range_flag\n if (gb.readBool()) { // colour_description_present_flag\n gb.readBits(24); // colour_primaries & transfer_characteristics & matrix_coefficients\n }\n }\n if (gb.readBool()) { // chroma_loc_info_present_flag\n gb.readUEG(); // chroma_sample_loc_type_top_field\n gb.readUEG(); // chroma_sample_loc_type_bottom_field\n }\n if (gb.readBool()) { // timing_info_present_flag\n let num_units_in_tick = gb.readBits(32);\n let time_scale = gb.readBits(32);\n fps_fixed = gb.readBool(); // fixed_frame_rate_flag\n\n fps_num = time_scale;\n fps_den = num_units_in_tick * 2;\n fps = fps_num / fps_den;\n }\n }\n\n let sarScale = 1;\n if (sar_width !== 1 || sar_height !== 1) {\n sarScale = sar_width / sar_height;\n }\n\n let crop_unit_x = 0, crop_unit_y = 0;\n if (chroma_format_idc === 0) {\n crop_unit_x = 1;\n crop_unit_y = 2 - frame_mbs_only_flag;\n } else {\n let sub_wc = (chroma_format_idc === 3) ? 1 : 2;\n let sub_hc = (chroma_format_idc === 1) ? 2 : 1;\n crop_unit_x = sub_wc;\n crop_unit_y = sub_hc * (2 - frame_mbs_only_flag);\n }\n\n let codec_width = (pic_width_in_mbs_minus1 + 1) * 16;\n let codec_height = (2 - frame_mbs_only_flag) * ((pic_height_in_map_units_minus1 + 1) * 16);\n\n codec_width -= (frame_crop_left_offset + frame_crop_right_offset) * crop_unit_x;\n codec_height -= (frame_crop_top_offset + frame_crop_bottom_offset) * crop_unit_y;\n\n let present_width = Math.ceil(codec_width * sarScale);\n\n gb.destroy();\n gb = null;\n\n return {\n profile_string: profile_string, // baseline, high, high10, ...\n level_string: level_string, // 3, 3.1, 4, 4.1, 5, 5.1, ...\n bit_depth: bit_depth, // 8bit, 10bit, ...\n chroma_format: chroma_format, // 4:2:0, 4:2:2, ...\n chroma_format_string: SPSParser.getChromaFormatString(chroma_format),\n\n frame_rate: {\n fixed: fps_fixed,\n fps: fps,\n fps_den: fps_den,\n fps_num: fps_num\n },\n\n sar_ratio: {\n width: sar_width,\n height: sar_height\n },\n\n codec_size: {\n width: codec_width,\n height: codec_height\n },\n\n present_size: {\n width: present_width,\n height: codec_height\n }\n };\n }\n\n static _skipScalingList(gb, count) {\n let last_scale = 8, next_scale = 8;\n let delta_scale = 0;\n for (let i = 0; i < count; i++) {\n if (next_scale !== 0) {\n delta_scale = gb.readSEG();\n next_scale = (last_scale + delta_scale + 256) % 256;\n }\n last_scale = (next_scale === 0) ? last_scale : next_scale;\n }\n }\n\n static getProfileString(profile_idc) {\n switch (profile_idc) {\n case 66:\n return 'Baseline';\n case 77:\n return 'Main';\n case 88:\n return 'Extended';\n case 100:\n return 'High';\n case 110:\n return 'High10';\n case 122:\n return 'High422';\n case 244:\n return 'High444';\n default:\n return 'Unknown';\n }\n }\n\n static getLevelString(level_idc) {\n return (level_idc / 10).toFixed(1);\n }\n\n static getChromaFormatString(chroma) {\n switch (chroma) {\n case 420:\n return '4:2:0';\n case 422:\n return '4:2:2';\n case 444:\n return '4:4:4';\n default:\n return 'Unknown';\n }\n }\n\n}\n\nexport default SPSParser;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Polyfill from './utils/polyfill.js';\nimport Features from './core/features.js';\nimport FlvPlayer from './player/flv-player.js';\nimport NativePlayer from './player/native-player.js';\nimport PlayerEvents from './player/player-events.js';\nimport {ErrorTypes, ErrorDetails} from './player/player-errors.js';\nimport LoggingControl from './utils/logging-control.js';\nimport {InvalidArgumentException} from './utils/exception.js';\n\n// here are all the interfaces\n\n// install polyfills\nPolyfill.install();\n\n\n// factory method\nfunction createPlayer(mediaDataSource, optionalConfig) {\n let mds = mediaDataSource;\n if (mds == null || typeof mds !== 'object') {\n throw new InvalidArgumentException('MediaDataSource must be an javascript object!');\n }\n\n if (!mds.hasOwnProperty('type')) {\n throw new InvalidArgumentException('MediaDataSource must has type field to indicate video file type!');\n }\n\n switch (mds.type) {\n case 'flv':\n return new FlvPlayer(mds, optionalConfig);\n default:\n return new NativePlayer(mds, optionalConfig);\n }\n}\n\n\n// feature detection\nfunction isSupported() {\n return Features.supportMSEH264Playback();\n}\n\nfunction getFeatureList() {\n return Features.getFeatureList();\n}\n\n\n// interfaces\nlet flvjs = {};\n\nflvjs.createPlayer = createPlayer;\nflvjs.isSupported = isSupported;\nflvjs.getFeatureList = getFeatureList;\n\nflvjs.Events = PlayerEvents;\nflvjs.ErrorTypes = ErrorTypes;\nflvjs.ErrorDetails = ErrorDetails;\n\nflvjs.FlvPlayer = FlvPlayer;\nflvjs.NativePlayer = NativePlayer;\nflvjs.LoggingControl = LoggingControl;\n\nObject.defineProperty(flvjs, 'version', {\n enumerable: true,\n get: function () {\n // replaced by browserify-versionify transform\n return '__VERSION__';\n }\n});\n\nexport default flvjs;","// entry/index file\n\n// make it compatible with browserify's umd wrapper\nmodule.exports = require('./flv.js').default;\n","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n/* fetch + stream IO loader. Currently working on chrome 43+.\n * fetch provides a better alternative http API to XMLHttpRequest\n *\n * fetch spec https://fetch.spec.whatwg.org/\n * stream spec https://streams.spec.whatwg.org/\n */\nclass FetchStreamLoader extends BaseLoader {\n\n static isSupported() {\n try {\n // fetch + stream is broken on Microsoft Edge. Disable before build 15048.\n // see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8196907/\n // Fixed in Jan 10, 2017. Build 15048+ removed from blacklist.\n let isWorkWellEdge = Browser.msedge && Browser.version.minor >= 15048;\n let browserNotBlacklisted = Browser.msedge ? isWorkWellEdge : true;\n return (self.fetch && self.ReadableStream && browserNotBlacklisted);\n } catch (e) {\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('fetch-stream-loader');\n this.TAG = 'FetchStreamLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = true;\n\n this._requestAbort = false;\n this._contentLength = null;\n this._receivedLength = 0;\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n super.destroy();\n }\n\n open(dataSource, range) {\n this._dataSource = dataSource;\n this._range = range;\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n\n let headers = new self.Headers();\n\n if (typeof seekConfig.headers === 'object') {\n let configHeaders = seekConfig.headers;\n for (let key in configHeaders) {\n if (configHeaders.hasOwnProperty(key)) {\n headers.append(key, configHeaders[key]);\n }\n }\n }\n\n let params = {\n method: 'GET',\n headers: headers,\n mode: 'cors',\n cache: 'default',\n // The default policy of Fetch API in the whatwg standard\n // Safari incorrectly indicates 'no-referrer' as default policy, fuck it\n referrerPolicy: 'no-referrer-when-downgrade'\n };\n\n // cors is enabled by default\n if (dataSource.cors === false) {\n // no-cors means 'disregard cors policy', which can only be used in ServiceWorker\n params.mode = 'same-origin';\n }\n\n // withCredentials is disabled by default\n if (dataSource.withCredentials) {\n params.credentials = 'include';\n }\n\n // referrerPolicy from config\n if (dataSource.referrerPolicy) {\n params.referrerPolicy = dataSource.referrerPolicy;\n }\n\n this._status = LoaderStatus.kConnecting;\n self.fetch(seekConfig.url, params).then((res) => {\n if (this._requestAbort) {\n this._requestAbort = false;\n this._status = LoaderStatus.kIdle;\n return;\n }\n if (res.ok && (res.status >= 200 && res.status <= 299)) {\n if (res.url !== seekConfig.url) {\n if (this._onURLRedirect) {\n let redirectedURL = this._seekHandler.removeURLParameters(res.url);\n this._onURLRedirect(redirectedURL);\n }\n }\n\n let lengthHeader = res.headers.get('Content-Length');\n if (lengthHeader != null) {\n this._contentLength = parseInt(lengthHeader);\n if (this._contentLength !== 0) {\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n }\n\n return this._pump.call(this, res.body.getReader());\n } else {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: res.status, msg: res.statusText});\n } else {\n throw new RuntimeException('FetchStreamLoader: Http code invalid, ' + res.status + ' ' + res.statusText);\n }\n }\n }).catch((e) => {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, {code: -1, msg: e.message});\n } else {\n throw e;\n }\n });\n }\n\n abort() {\n this._requestAbort = true;\n }\n\n _pump(reader) { // ReadableStreamReader\n return reader.read().then((result) => {\n if (result.done) {\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);\n }\n } else {\n if (this._requestAbort === true) {\n this._requestAbort = false;\n this._status = LoaderStatus.kComplete;\n return reader.cancel();\n }\n\n this._status = LoaderStatus.kBuffering;\n\n let chunk = result.value.buffer;\n let byteStart = this._range.from + this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n\n this._pump(reader);\n }\n }).catch((e) => {\n if (e.code === 11 && Browser.msedge) { // InvalidStateError on Microsoft Edge\n // Workaround: Edge may throw InvalidStateError after ReadableStreamReader.cancel() call\n // Ignore the unknown exception.\n // Related issue: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11265202/\n return;\n }\n\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if ((e.code === 19 || e.message === 'network error') && // NETWORK_ERR\n (this._contentLength === null ||\n (this._contentLength !== null && this._receivedLength < this._contentLength))) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: e.code, msg: 'Fetch stream meet Early-EOF'};\n } else {\n type = LoaderErrors.EXCEPTION;\n info = {code: e.code, msg: e.message};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n });\n }\n\n}\n\nexport default FetchStreamLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport SpeedSampler from './speed-sampler.js';\nimport {LoaderStatus, LoaderErrors} from './loader.js';\nimport FetchStreamLoader from './fetch-stream-loader.js';\nimport MozChunkedLoader from './xhr-moz-chunked-loader.js';\nimport MSStreamLoader from './xhr-msstream-loader.js';\nimport RangeLoader from './xhr-range-loader.js';\nimport WebSocketLoader from './websocket-loader.js';\nimport RangeSeekHandler from './range-seek-handler.js';\nimport ParamSeekHandler from './param-seek-handler.js';\nimport {RuntimeException, IllegalStateException, InvalidArgumentException} from '../utils/exception.js';\n\n/**\n * DataSource: {\n * url: string,\n * filesize: number,\n * cors: boolean,\n * withCredentials: boolean\n * }\n * \n */\n\n// Manage IO Loaders\nclass IOController {\n\n constructor(dataSource, config, extraData) {\n this.TAG = 'IOController';\n\n this._config = config;\n this._extraData = extraData;\n\n this._stashInitialSize = 1024 * 384; // default initial size: 384KB\n if (config.stashInitialSize != undefined && config.stashInitialSize > 0) {\n // apply from config\n this._stashInitialSize = config.stashInitialSize;\n }\n\n this._stashUsed = 0;\n this._stashSize = this._stashInitialSize;\n this._bufferSize = 1024 * 1024 * 3; // initial size: 3MB\n this._stashBuffer = new ArrayBuffer(this._bufferSize);\n this._stashByteStart = 0;\n this._enableStash = true;\n if (config.enableStashBuffer === false) {\n this._enableStash = false;\n }\n\n this._loader = null;\n this._loaderClass = null;\n this._seekHandler = null;\n\n this._dataSource = dataSource;\n this._isWebSocketURL = /wss?:\\/\\/(.+?)/.test(dataSource.url);\n this._refTotalLength = dataSource.filesize ? dataSource.filesize : null;\n this._totalLength = this._refTotalLength;\n this._fullRequestFlag = false;\n this._currentRange = null;\n this._redirectedURL = null;\n\n this._speedNormalized = 0;\n this._speedSampler = new SpeedSampler();\n this._speedNormalizeList = [64, 128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096];\n\n this._isEarlyEofReconnecting = false;\n\n this._paused = false;\n this._resumeFrom = 0;\n\n this._onDataArrival = null;\n this._onSeeked = null;\n this._onError = null;\n this._onComplete = null;\n this._onRedirect = null;\n this._onRecoveredEarlyEof = null;\n\n this._selectSeekHandler();\n this._selectLoader();\n this._createLoader();\n }\n\n destroy() {\n if (this._loader.isWorking()) {\n this._loader.abort();\n }\n this._loader.destroy();\n this._loader = null;\n this._loaderClass = null;\n this._dataSource = null;\n this._stashBuffer = null;\n this._stashUsed = this._stashSize = this._bufferSize = this._stashByteStart = 0;\n this._currentRange = null;\n this._speedSampler = null;\n\n this._isEarlyEofReconnecting = false;\n\n this._onDataArrival = null;\n this._onSeeked = null;\n this._onError = null;\n this._onComplete = null;\n this._onRedirect = null;\n this._onRecoveredEarlyEof = null;\n\n this._extraData = null;\n }\n\n isWorking() {\n return this._loader && this._loader.isWorking() && !this._paused;\n }\n\n isPaused() {\n return this._paused;\n }\n\n get status() {\n return this._loader.status;\n }\n\n get extraData() {\n return this._extraData;\n }\n\n set extraData(data) {\n this._extraData = data;\n }\n\n // prototype: function onDataArrival(chunks: ArrayBuffer, byteStart: number): number\n get onDataArrival() {\n return this._onDataArrival;\n }\n\n set onDataArrival(callback) {\n this._onDataArrival = callback;\n }\n\n get onSeeked() {\n return this._onSeeked;\n }\n\n set onSeeked(callback) {\n this._onSeeked = callback;\n }\n\n // prototype: function onError(type: number, info: {code: number, msg: string}): void\n get onError() {\n return this._onError;\n }\n\n set onError(callback) {\n this._onError = callback;\n }\n\n get onComplete() {\n return this._onComplete;\n }\n\n set onComplete(callback) {\n this._onComplete = callback;\n }\n\n get onRedirect() {\n return this._onRedirect;\n }\n\n set onRedirect(callback) {\n this._onRedirect = callback;\n }\n\n get onRecoveredEarlyEof() {\n return this._onRecoveredEarlyEof;\n }\n\n set onRecoveredEarlyEof(callback) {\n this._onRecoveredEarlyEof = callback;\n }\n\n get currentURL() {\n return this._dataSource.url;\n }\n\n get hasRedirect() {\n return (this._redirectedURL != null || this._dataSource.redirectedURL != undefined);\n }\n\n get currentRedirectedURL() {\n return this._redirectedURL || this._dataSource.redirectedURL;\n }\n\n // in KB/s\n get currentSpeed() {\n if (this._loaderClass === RangeLoader) {\n // SpeedSampler is inaccuracy if loader is RangeLoader\n return this._loader.currentSpeed;\n }\n return this._speedSampler.lastSecondKBps;\n }\n\n get loaderType() {\n return this._loader.type;\n }\n\n _selectSeekHandler() {\n let config = this._config;\n\n if (config.seekType === 'range') {\n this._seekHandler = new RangeSeekHandler(this._config.rangeLoadZeroStart);\n } else if (config.seekType === 'param') {\n let paramStart = config.seekParamStart || 'bstart';\n let paramEnd = config.seekParamEnd || 'bend';\n\n this._seekHandler = new ParamSeekHandler(paramStart, paramEnd);\n } else if (config.seekType === 'custom') {\n if (typeof config.customSeekHandler !== 'function') {\n throw new InvalidArgumentException('Custom seekType specified in config but invalid customSeekHandler!');\n }\n this._seekHandler = new config.customSeekHandler();\n } else {\n throw new InvalidArgumentException(`Invalid seekType in config: ${config.seekType}`);\n }\n }\n\n _selectLoader() {\n if (this._isWebSocketURL) {\n this._loaderClass = WebSocketLoader;\n } else if (FetchStreamLoader.isSupported()) {\n this._loaderClass = FetchStreamLoader;\n } else if (MozChunkedLoader.isSupported()) {\n this._loaderClass = MozChunkedLoader;\n } else if (RangeLoader.isSupported()) {\n this._loaderClass = RangeLoader;\n } else {\n throw new RuntimeException('Your browser doesn\\'t support xhr with arraybuffer responseType!');\n }\n }\n\n _createLoader() {\n this._loader = new this._loaderClass(this._seekHandler, this._config);\n if (this._loader.needStashBuffer === false) {\n this._enableStash = false;\n }\n this._loader.onContentLengthKnown = this._onContentLengthKnown.bind(this);\n this._loader.onURLRedirect = this._onURLRedirect.bind(this);\n this._loader.onDataArrival = this._onLoaderChunkArrival.bind(this);\n this._loader.onComplete = this._onLoaderComplete.bind(this);\n this._loader.onError = this._onLoaderError.bind(this);\n }\n\n open(optionalFrom) {\n this._currentRange = {from: 0, to: -1};\n if (optionalFrom) {\n this._currentRange.from = optionalFrom;\n }\n\n this._speedSampler.reset();\n if (!optionalFrom) {\n this._fullRequestFlag = true;\n }\n\n this._loader.open(this._dataSource, Object.assign({}, this._currentRange));\n }\n\n abort() {\n this._loader.abort();\n\n if (this._paused) {\n this._paused = false;\n this._resumeFrom = 0;\n }\n }\n\n pause() {\n if (this.isWorking()) {\n this._loader.abort();\n\n if (this._stashUsed !== 0) {\n this._resumeFrom = this._stashByteStart;\n this._currentRange.to = this._stashByteStart - 1;\n } else {\n this._resumeFrom = this._currentRange.to + 1;\n }\n this._stashUsed = 0;\n this._stashByteStart = 0;\n this._paused = true;\n }\n }\n\n resume() {\n if (this._paused) {\n this._paused = false;\n let bytes = this._resumeFrom;\n this._resumeFrom = 0;\n this._internalSeek(bytes, true);\n }\n }\n\n seek(bytes) {\n this._paused = false;\n this._stashUsed = 0;\n this._stashByteStart = 0;\n this._internalSeek(bytes, true);\n }\n\n /**\n * When seeking request is from media seeking, unconsumed stash data should be dropped\n * However, stash data shouldn't be dropped if seeking requested from http reconnection\n *\n * @dropUnconsumed: Ignore and discard all unconsumed data in stash buffer\n */\n _internalSeek(bytes, dropUnconsumed) {\n if (this._loader.isWorking()) {\n this._loader.abort();\n }\n\n // dispatch & flush stash buffer before seek\n this._flushStashBuffer(dropUnconsumed);\n\n this._loader.destroy();\n this._loader = null;\n\n let requestRange = {from: bytes, to: -1};\n this._currentRange = {from: requestRange.from, to: -1};\n\n this._speedSampler.reset();\n this._stashSize = this._stashInitialSize;\n this._createLoader();\n this._loader.open(this._dataSource, requestRange);\n\n if (this._onSeeked) {\n this._onSeeked();\n }\n }\n\n updateUrl(url) {\n if (!url || typeof url !== 'string' || url.length === 0) {\n throw new InvalidArgumentException('Url must be a non-empty string!');\n }\n\n this._dataSource.url = url;\n\n // TODO: replace with new url\n }\n\n _expandBuffer(expectedBytes) {\n let bufferNewSize = this._stashSize;\n while (bufferNewSize + 1024 * 1024 * 1 < expectedBytes) {\n bufferNewSize *= 2;\n }\n\n bufferNewSize += 1024 * 1024 * 1; // bufferSize = stashSize + 1MB\n if (bufferNewSize === this._bufferSize) {\n return;\n }\n\n let newBuffer = new ArrayBuffer(bufferNewSize);\n\n if (this._stashUsed > 0) { // copy existing data into new buffer\n let stashOldArray = new Uint8Array(this._stashBuffer, 0, this._stashUsed);\n let stashNewArray = new Uint8Array(newBuffer, 0, bufferNewSize);\n stashNewArray.set(stashOldArray, 0);\n }\n\n this._stashBuffer = newBuffer;\n this._bufferSize = bufferNewSize;\n }\n\n _normalizeSpeed(input) {\n let list = this._speedNormalizeList;\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (input < list[0]) {\n return list[0];\n }\n\n // binary search\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (input >= list[mid] && input < list[mid + 1])) {\n return list[mid];\n } else if (list[mid] < input) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n }\n\n _adjustStashSize(normalized) {\n let stashSizeKB = 0;\n\n if (this._config.isLive) {\n // live stream: always use single normalized speed for size of stashSizeKB\n stashSizeKB = normalized;\n } else {\n if (normalized < 512) {\n stashSizeKB = normalized;\n } else if (normalized >= 512 && normalized <= 1024) {\n stashSizeKB = Math.floor(normalized * 1.5);\n } else {\n stashSizeKB = normalized * 2;\n }\n }\n\n if (stashSizeKB > 8192) {\n stashSizeKB = 8192;\n }\n\n let bufferSize = stashSizeKB * 1024 + 1024 * 1024 * 1; // stashSize + 1MB\n if (this._bufferSize < bufferSize) {\n this._expandBuffer(bufferSize);\n }\n this._stashSize = stashSizeKB * 1024;\n }\n\n _dispatchChunks(chunks, byteStart) {\n this._currentRange.to = byteStart + chunks.byteLength - 1;\n return this._onDataArrival(chunks, byteStart);\n }\n\n _onURLRedirect(redirectedURL) {\n this._redirectedURL = redirectedURL;\n if (this._onRedirect) {\n this._onRedirect(redirectedURL);\n }\n }\n\n _onContentLengthKnown(contentLength) {\n if (contentLength && this._fullRequestFlag) {\n this._totalLength = contentLength;\n this._fullRequestFlag = false;\n }\n }\n\n _onLoaderChunkArrival(chunk, byteStart, receivedLength) {\n if (!this._onDataArrival) {\n throw new IllegalStateException('IOController: No existing consumer (onDataArrival) callback!');\n }\n if (this._paused) {\n return;\n }\n if (this._isEarlyEofReconnecting) {\n // Auto-reconnect for EarlyEof succeed, notify to upper-layer by callback\n this._isEarlyEofReconnecting = false;\n if (this._onRecoveredEarlyEof) {\n this._onRecoveredEarlyEof();\n }\n }\n\n this._speedSampler.addBytes(chunk.byteLength);\n\n // adjust stash buffer size according to network speed dynamically\n let KBps = this._speedSampler.lastSecondKBps;\n if (KBps !== 0) {\n let normalized = this._normalizeSpeed(KBps);\n if (this._speedNormalized !== normalized) {\n this._speedNormalized = normalized;\n this._adjustStashSize(normalized);\n }\n }\n\n if (!this._enableStash) { // disable stash\n if (this._stashUsed === 0) {\n // dispatch chunk directly to consumer;\n // check ret value (consumed bytes) and stash unconsumed to stashBuffer\n let consumed = this._dispatchChunks(chunk, byteStart);\n if (consumed < chunk.byteLength) { // unconsumed data remain.\n let remain = chunk.byteLength - consumed;\n if (remain > this._bufferSize) {\n this._expandBuffer(remain);\n }\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n stashArray.set(new Uint8Array(chunk, consumed), 0);\n this._stashUsed += remain;\n this._stashByteStart = byteStart + consumed;\n }\n } else {\n // else: Merge chunk into stashBuffer, and dispatch stashBuffer to consumer.\n if (this._stashUsed + chunk.byteLength > this._bufferSize) {\n this._expandBuffer(this._stashUsed + chunk.byteLength);\n }\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n stashArray.set(new Uint8Array(chunk), this._stashUsed);\n this._stashUsed += chunk.byteLength;\n let consumed = this._dispatchChunks(this._stashBuffer.slice(0, this._stashUsed), this._stashByteStart);\n if (consumed < this._stashUsed && consumed > 0) { // unconsumed data remain\n let remainArray = new Uint8Array(this._stashBuffer, consumed);\n stashArray.set(remainArray, 0);\n }\n this._stashUsed -= consumed;\n this._stashByteStart += consumed;\n }\n } else { // enable stash\n if (this._stashUsed === 0 && this._stashByteStart === 0) { // seeked? or init chunk?\n // This is the first chunk after seek action\n this._stashByteStart = byteStart;\n }\n if (this._stashUsed + chunk.byteLength <= this._stashSize) {\n // just stash\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._stashSize);\n stashArray.set(new Uint8Array(chunk), this._stashUsed);\n this._stashUsed += chunk.byteLength;\n } else { // stashUsed + chunkSize > stashSize, size limit exceeded\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n if (this._stashUsed > 0) { // There're stash datas in buffer\n // dispatch the whole stashBuffer, and stash remain data\n // then append chunk to stashBuffer (stash)\n let buffer = this._stashBuffer.slice(0, this._stashUsed);\n let consumed = this._dispatchChunks(buffer, this._stashByteStart);\n if (consumed < buffer.byteLength) {\n if (consumed > 0) {\n let remainArray = new Uint8Array(buffer, consumed);\n stashArray.set(remainArray, 0);\n this._stashUsed = remainArray.byteLength;\n this._stashByteStart += consumed;\n }\n } else {\n this._stashUsed = 0;\n this._stashByteStart += consumed;\n }\n if (this._stashUsed + chunk.byteLength > this._bufferSize) {\n this._expandBuffer(this._stashUsed + chunk.byteLength);\n stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n }\n stashArray.set(new Uint8Array(chunk), this._stashUsed);\n this._stashUsed += chunk.byteLength;\n } else { // stash buffer empty, but chunkSize > stashSize (oh, holy shit)\n // dispatch chunk directly and stash remain data\n let consumed = this._dispatchChunks(chunk, byteStart);\n if (consumed < chunk.byteLength) {\n let remain = chunk.byteLength - consumed;\n if (remain > this._bufferSize) {\n this._expandBuffer(remain);\n stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n }\n stashArray.set(new Uint8Array(chunk, consumed), 0);\n this._stashUsed += remain;\n this._stashByteStart = byteStart + consumed;\n }\n }\n }\n }\n }\n\n _flushStashBuffer(dropUnconsumed) {\n if (this._stashUsed > 0) {\n let buffer = this._stashBuffer.slice(0, this._stashUsed);\n let consumed = this._dispatchChunks(buffer, this._stashByteStart);\n let remain = buffer.byteLength - consumed;\n\n if (consumed < buffer.byteLength) {\n if (dropUnconsumed) {\n Log.w(this.TAG, `${remain} bytes unconsumed data remain when flush buffer, dropped`);\n } else {\n if (consumed > 0) {\n let stashArray = new Uint8Array(this._stashBuffer, 0, this._bufferSize);\n let remainArray = new Uint8Array(buffer, consumed);\n stashArray.set(remainArray, 0);\n this._stashUsed = remainArray.byteLength;\n this._stashByteStart += consumed;\n }\n return 0;\n }\n }\n this._stashUsed = 0;\n this._stashByteStart = 0;\n return remain;\n }\n return 0;\n }\n\n _onLoaderComplete(from, to) {\n // Force-flush stash buffer, and drop unconsumed data\n this._flushStashBuffer(true);\n\n if (this._onComplete) {\n this._onComplete(this._extraData);\n }\n }\n\n _onLoaderError(type, data) {\n Log.e(this.TAG, `Loader error, code = ${data.code}, msg = ${data.msg}`);\n\n this._flushStashBuffer(false);\n\n if (this._isEarlyEofReconnecting) {\n // Auto-reconnect for EarlyEof failed, throw UnrecoverableEarlyEof error to upper-layer\n this._isEarlyEofReconnecting = false;\n type = LoaderErrors.UNRECOVERABLE_EARLY_EOF;\n }\n\n switch (type) {\n case LoaderErrors.EARLY_EOF: {\n if (!this._config.isLive) {\n // Do internal http reconnect if not live stream\n if (this._totalLength) {\n let nextFrom = this._currentRange.to + 1;\n if (nextFrom < this._totalLength) {\n Log.w(this.TAG, 'Connection lost, trying reconnect...');\n this._isEarlyEofReconnecting = true;\n this._internalSeek(nextFrom, false);\n }\n return;\n }\n // else: We don't know totalLength, throw UnrecoverableEarlyEof\n }\n // live stream: throw UnrecoverableEarlyEof error to upper-layer\n type = LoaderErrors.UNRECOVERABLE_EARLY_EOF;\n break;\n }\n case LoaderErrors.UNRECOVERABLE_EARLY_EOF:\n case LoaderErrors.CONNECTING_TIMEOUT:\n case LoaderErrors.HTTP_STATUS_CODE_INVALID:\n case LoaderErrors.EXCEPTION:\n break;\n }\n\n if (this._onError) {\n this._onError(type, data);\n } else {\n throw new RuntimeException('IOException: ' + data.msg);\n }\n }\n\n}\n\nexport default IOController;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {NotImplementedException} from '../utils/exception.js';\n\nexport const LoaderStatus = {\n kIdle: 0,\n kConnecting: 1,\n kBuffering: 2,\n kError: 3,\n kComplete: 4\n};\n\nexport const LoaderErrors = {\n OK: 'OK',\n EXCEPTION: 'Exception',\n HTTP_STATUS_CODE_INVALID: 'HttpStatusCodeInvalid',\n CONNECTING_TIMEOUT: 'ConnectingTimeout',\n EARLY_EOF: 'EarlyEof',\n UNRECOVERABLE_EARLY_EOF: 'UnrecoverableEarlyEof'\n};\n\n/* Loader has callbacks which have following prototypes:\n * function onContentLengthKnown(contentLength: number): void\n * function onURLRedirect(url: string): void\n * function onDataArrival(chunk: ArrayBuffer, byteStart: number, receivedLength: number): void\n * function onError(errorType: number, errorInfo: {code: number, msg: string}): void\n * function onComplete(rangeFrom: number, rangeTo: number): void\n */\nexport class BaseLoader {\n\n constructor(typeName) {\n this._type = typeName || 'undefined';\n this._status = LoaderStatus.kIdle;\n this._needStash = false;\n // callbacks\n this._onContentLengthKnown = null;\n this._onURLRedirect = null;\n this._onDataArrival = null;\n this._onError = null;\n this._onComplete = null;\n }\n\n destroy() {\n this._status = LoaderStatus.kIdle;\n this._onContentLengthKnown = null;\n this._onURLRedirect = null;\n this._onDataArrival = null;\n this._onError = null;\n this._onComplete = null;\n }\n\n isWorking() {\n return this._status === LoaderStatus.kConnecting || this._status === LoaderStatus.kBuffering;\n }\n\n get type() {\n return this._type;\n }\n\n get status() {\n return this._status;\n }\n\n get needStashBuffer() {\n return this._needStash;\n }\n\n get onContentLengthKnown() {\n return this._onContentLengthKnown;\n }\n\n set onContentLengthKnown(callback) {\n this._onContentLengthKnown = callback;\n }\n\n get onURLRedirect() {\n return this._onURLRedirect;\n }\n\n set onURLRedirect(callback) {\n this._onURLRedirect = callback;\n }\n\n get onDataArrival() {\n return this._onDataArrival;\n }\n\n set onDataArrival(callback) {\n this._onDataArrival = callback;\n }\n\n get onError() {\n return this._onError;\n }\n\n set onError(callback) {\n this._onError = callback;\n }\n\n get onComplete() {\n return this._onComplete;\n }\n\n set onComplete(callback) {\n this._onComplete = callback;\n }\n\n // pure virtual\n open(dataSource, range) {\n throw new NotImplementedException('Unimplemented abstract function!');\n }\n\n abort() {\n throw new NotImplementedException('Unimplemented abstract function!');\n }\n\n\n}","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass ParamSeekHandler {\n\n constructor(paramStart, paramEnd) {\n this._startName = paramStart;\n this._endName = paramEnd;\n }\n\n getConfig(baseUrl, range) {\n let url = baseUrl;\n\n if (range.from !== 0 || range.to !== -1) {\n let needAnd = true;\n if (url.indexOf('?') === -1) {\n url += '?';\n needAnd = false;\n }\n\n if (needAnd) {\n url += '&';\n }\n\n url += `${this._startName}=${range.from.toString()}`;\n\n if (range.to !== -1) {\n url += `&${this._endName}=${range.to.toString()}`;\n }\n }\n\n return {\n url: url,\n headers: {}\n };\n }\n\n removeURLParameters(seekedURL) {\n let baseURL = seekedURL.split('?')[0];\n let params = undefined;\n\n let queryIndex = seekedURL.indexOf('?');\n if (queryIndex !== -1) {\n params = seekedURL.substring(queryIndex + 1);\n }\n\n let resultParams = '';\n\n if (params != undefined && params.length > 0) {\n let pairs = params.split('&');\n\n for (let i = 0; i < pairs.length; i++) {\n let pair = pairs[i].split('=');\n let requireAnd = (i > 0);\n\n if (pair[0] !== this._startName && pair[0] !== this._endName) {\n if (requireAnd) {\n resultParams += '&';\n }\n resultParams += pairs[i];\n }\n }\n }\n\n return (resultParams.length === 0) ? baseURL : baseURL + '?' + resultParams;\n }\n\n}\n\nexport default ParamSeekHandler;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass RangeSeekHandler {\n\n constructor(zeroStart) {\n this._zeroStart = zeroStart || false;\n }\n\n getConfig(url, range) {\n let headers = {};\n\n if (range.from !== 0 || range.to !== -1) {\n let param;\n if (range.to !== -1) {\n param = `bytes=${range.from.toString()}-${range.to.toString()}`;\n } else {\n param = `bytes=${range.from.toString()}-`;\n }\n headers['Range'] = param;\n } else if (this._zeroStart) {\n headers['Range'] = 'bytes=0-';\n }\n\n return {\n url: url,\n headers: headers\n };\n }\n\n removeURLParameters(seekedURL) {\n return seekedURL;\n }\n\n}\n\nexport default RangeSeekHandler;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Utility class to calculate realtime network I/O speed\nclass SpeedSampler {\n\n constructor() {\n // milliseconds\n this._firstCheckpoint = 0;\n this._lastCheckpoint = 0;\n this._intervalBytes = 0;\n this._totalBytes = 0;\n this._lastSecondBytes = 0;\n\n // compatibility detection\n if (self.performance && self.performance.now) {\n this._now = self.performance.now.bind(self.performance);\n } else {\n this._now = Date.now;\n }\n }\n\n reset() {\n this._firstCheckpoint = this._lastCheckpoint = 0;\n this._totalBytes = this._intervalBytes = 0;\n this._lastSecondBytes = 0;\n }\n\n addBytes(bytes) {\n if (this._firstCheckpoint === 0) {\n this._firstCheckpoint = this._now();\n this._lastCheckpoint = this._firstCheckpoint;\n this._intervalBytes += bytes;\n this._totalBytes += bytes;\n } else if (this._now() - this._lastCheckpoint < 1000) {\n this._intervalBytes += bytes;\n this._totalBytes += bytes;\n } else { // duration >= 1000\n this._lastSecondBytes = this._intervalBytes;\n this._intervalBytes = bytes;\n this._totalBytes += bytes;\n this._lastCheckpoint = this._now();\n }\n }\n\n get currentKBps() {\n this.addBytes(0);\n\n let durationSeconds = (this._now() - this._lastCheckpoint) / 1000;\n if (durationSeconds == 0) durationSeconds = 1;\n return (this._intervalBytes / durationSeconds) / 1024;\n }\n\n get lastSecondKBps() {\n this.addBytes(0);\n\n if (this._lastSecondBytes !== 0) {\n return this._lastSecondBytes / 1024;\n } else { // lastSecondBytes === 0\n if (this._now() - this._lastCheckpoint >= 500) {\n // if time interval since last checkpoint has exceeded 500ms\n // the speed is nearly accurate\n return this.currentKBps;\n } else {\n // We don't know\n return 0;\n }\n }\n }\n\n get averageKBps() {\n let durationSeconds = (this._now() - this._firstCheckpoint) / 1000;\n return (this._totalBytes / durationSeconds) / 1024;\n }\n\n}\n\nexport default SpeedSampler;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n// For FLV over WebSocket live stream\nclass WebSocketLoader extends BaseLoader {\n\n static isSupported() {\n try {\n return (typeof self.WebSocket !== 'undefined');\n } catch (e) {\n return false;\n }\n }\n\n constructor() {\n super('websocket-loader');\n this.TAG = 'WebSocketLoader';\n\n this._needStash = true;\n\n this._ws = null;\n this._requestAbort = false;\n this._receivedLength = 0;\n }\n\n destroy() {\n if (this._ws) {\n this.abort();\n }\n super.destroy();\n }\n\n open(dataSource) {\n try {\n let ws = this._ws = new self.WebSocket(dataSource.url);\n ws.binaryType = 'arraybuffer';\n ws.onopen = this._onWebSocketOpen.bind(this);\n ws.onclose = this._onWebSocketClose.bind(this);\n ws.onmessage = this._onWebSocketMessage.bind(this);\n ws.onerror = this._onWebSocketError.bind(this);\n\n this._status = LoaderStatus.kConnecting;\n } catch (e) {\n this._status = LoaderStatus.kError;\n\n let info = {code: e.code, msg: e.message};\n\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n }\n\n abort() {\n let ws = this._ws;\n if (ws && (ws.readyState === 0 || ws.readyState === 1)) { // CONNECTING || OPEN\n this._requestAbort = true;\n ws.close();\n }\n\n this._ws = null;\n this._status = LoaderStatus.kComplete;\n }\n\n _onWebSocketOpen(e) {\n this._status = LoaderStatus.kBuffering;\n }\n\n _onWebSocketClose(e) {\n if (this._requestAbort === true) {\n this._requestAbort = false;\n return;\n }\n\n this._status = LoaderStatus.kComplete;\n\n if (this._onComplete) {\n this._onComplete(0, this._receivedLength - 1);\n }\n }\n\n _onWebSocketMessage(e) {\n if (e.data instanceof ArrayBuffer) {\n this._dispatchArrayBuffer(e.data);\n } else if (e.data instanceof Blob) {\n let reader = new FileReader();\n reader.onload = () => {\n this._dispatchArrayBuffer(reader.result);\n };\n reader.readAsArrayBuffer(e.data);\n } else {\n this._status = LoaderStatus.kError;\n let info = {code: -1, msg: 'Unsupported WebSocket message type: ' + e.data.constructor.name};\n\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n }\n\n _dispatchArrayBuffer(arraybuffer) {\n let chunk = arraybuffer;\n let byteStart = this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n }\n\n _onWebSocketError(e) {\n this._status = LoaderStatus.kError;\n\n let info = {\n code: e.code,\n msg: e.message\n };\n\n if (this._onError) {\n this._onError(LoaderErrors.EXCEPTION, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n}\n\nexport default WebSocketLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n// For FireFox browser which supports `xhr.responseType = 'moz-chunked-arraybuffer'`\nclass MozChunkedLoader extends BaseLoader {\n\n static isSupported() {\n try {\n let xhr = new XMLHttpRequest();\n // Firefox 37- requires .open() to be called before setting responseType\n xhr.open('GET', 'https://example.com', true);\n xhr.responseType = 'moz-chunked-arraybuffer';\n return (xhr.responseType === 'moz-chunked-arraybuffer');\n } catch (e) {\n Log.w('MozChunkedLoader', e.message);\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('xhr-moz-chunked-loader');\n this.TAG = 'MozChunkedLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = true;\n\n this._xhr = null;\n this._requestAbort = false;\n this._contentLength = null;\n this._receivedLength = 0;\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr.onprogress = null;\n this._xhr.onloadend = null;\n this._xhr.onerror = null;\n this._xhr = null;\n }\n super.destroy();\n }\n\n open(dataSource, range) {\n this._dataSource = dataSource;\n this._range = range;\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL && dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n this._requestURL = seekConfig.url;\n\n let xhr = this._xhr = new XMLHttpRequest();\n xhr.open('GET', seekConfig.url, true);\n xhr.responseType = 'moz-chunked-arraybuffer';\n xhr.onreadystatechange = this._onReadyStateChange.bind(this);\n xhr.onprogress = this._onProgress.bind(this);\n xhr.onloadend = this._onLoadEnd.bind(this);\n xhr.onerror = this._onXhrError.bind(this);\n\n // cors is auto detected and enabled by xhr\n\n // withCredentials is disabled by default\n if (dataSource.withCredentials && xhr['withCredentials']) {\n xhr.withCredentials = true;\n }\n\n if (typeof seekConfig.headers === 'object') {\n let headers = seekConfig.headers;\n\n for (let key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n }\n\n this._status = LoaderStatus.kConnecting;\n xhr.send();\n }\n\n abort() {\n this._requestAbort = true;\n if (this._xhr) {\n this._xhr.abort();\n }\n this._status = LoaderStatus.kComplete;\n }\n\n _onReadyStateChange(e) {\n let xhr = e.target;\n\n if (xhr.readyState === 2) { // HEADERS_RECEIVED\n if (xhr.responseURL != undefined && xhr.responseURL !== this._requestURL) {\n if (this._onURLRedirect) {\n let redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);\n this._onURLRedirect(redirectedURL);\n }\n }\n\n if (xhr.status !== 0 && (xhr.status < 200 || xhr.status > 299)) {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});\n } else {\n throw new RuntimeException('MozChunkedLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);\n }\n } else {\n this._status = LoaderStatus.kBuffering;\n }\n }\n }\n\n _onProgress(e) {\n if (this._status === LoaderStatus.kError) {\n // Ignore error response\n return;\n }\n\n if (this._contentLength === null) {\n if (e.total !== null && e.total !== 0) {\n this._contentLength = e.total;\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n }\n\n let chunk = e.target.response;\n let byteStart = this._range.from + this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n }\n\n _onLoadEnd(e) {\n if (this._requestAbort === true) {\n this._requestAbort = false;\n return;\n } else if (this._status === LoaderStatus.kError) {\n return;\n }\n\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);\n }\n }\n\n _onXhrError(e) {\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if (this._contentLength && e.loaded < this._contentLength) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: 'Moz-Chunked stream meet Early-Eof'};\n } else {\n type = LoaderErrors.EXCEPTION;\n info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n}\n\nexport default MozChunkedLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n/* Notice: ms-stream may cause IE/Edge browser crash if seek too frequently!!!\n * The browser may crash in wininet.dll. Disable for now.\n *\n * For IE11/Edge browser by microsoft which supports `xhr.responseType = 'ms-stream'`\n * Notice that ms-stream API sucks. The buffer is always expanding along with downloading.\n *\n * We need to abort the xhr if buffer size exceeded limit size (e.g. 16 MiB), then do reconnect.\n * in order to release previous ArrayBuffer to avoid memory leak\n *\n * Otherwise, the ArrayBuffer will increase to a terrible size that equals final file size.\n */\nclass MSStreamLoader extends BaseLoader {\n\n static isSupported() {\n try {\n if (typeof self.MSStream === 'undefined' || typeof self.MSStreamReader === 'undefined') {\n return false;\n }\n\n let xhr = new XMLHttpRequest();\n xhr.open('GET', 'https://example.com', true);\n xhr.responseType = 'ms-stream';\n return (xhr.responseType === 'ms-stream');\n } catch (e) {\n Log.w('MSStreamLoader', e.message);\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('xhr-msstream-loader');\n this.TAG = 'MSStreamLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = true;\n\n this._xhr = null;\n this._reader = null; // MSStreamReader\n\n this._totalRange = null;\n this._currentRange = null;\n\n this._currentRequestURL = null;\n this._currentRedirectedURL = null;\n\n this._contentLength = null;\n this._receivedLength = 0;\n\n this._bufferLimit = 16 * 1024 * 1024; // 16MB\n this._lastTimeBufferSize = 0;\n this._isReconnecting = false;\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n if (this._reader) {\n this._reader.onprogress = null;\n this._reader.onload = null;\n this._reader.onerror = null;\n this._reader = null;\n }\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr = null;\n }\n super.destroy();\n }\n\n open(dataSource, range) {\n this._internalOpen(dataSource, range, false);\n }\n\n _internalOpen(dataSource, range, isSubrange) {\n this._dataSource = dataSource;\n\n if (!isSubrange) {\n this._totalRange = range;\n } else {\n this._currentRange = range;\n }\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL) {\n if (this._currentRedirectedURL != undefined) {\n sourceURL = this._currentRedirectedURL;\n } else if (dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n this._currentRequestURL = seekConfig.url;\n\n let reader = this._reader = new self.MSStreamReader();\n reader.onprogress = this._msrOnProgress.bind(this);\n reader.onload = this._msrOnLoad.bind(this);\n reader.onerror = this._msrOnError.bind(this);\n\n let xhr = this._xhr = new XMLHttpRequest();\n xhr.open('GET', seekConfig.url, true);\n xhr.responseType = 'ms-stream';\n xhr.onreadystatechange = this._xhrOnReadyStateChange.bind(this);\n xhr.onerror = this._xhrOnError.bind(this);\n\n if (dataSource.withCredentials) {\n xhr.withCredentials = true;\n }\n\n if (typeof seekConfig.headers === 'object') {\n let headers = seekConfig.headers;\n\n for (let key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n }\n\n if (this._isReconnecting) {\n this._isReconnecting = false;\n } else {\n this._status = LoaderStatus.kConnecting;\n }\n xhr.send();\n }\n\n abort() {\n this._internalAbort();\n this._status = LoaderStatus.kComplete;\n }\n\n _internalAbort() {\n if (this._reader) {\n if (this._reader.readyState === 1) { // LOADING\n this._reader.abort();\n }\n this._reader.onprogress = null;\n this._reader.onload = null;\n this._reader.onerror = null;\n this._reader = null;\n }\n if (this._xhr) {\n this._xhr.abort();\n this._xhr.onreadystatechange = null;\n this._xhr = null;\n }\n }\n\n _xhrOnReadyStateChange(e) {\n let xhr = e.target;\n\n if (xhr.readyState === 2) { // HEADERS_RECEIVED\n if (xhr.status >= 200 && xhr.status <= 299) {\n this._status = LoaderStatus.kBuffering;\n\n if (xhr.responseURL != undefined) {\n let redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);\n if (xhr.responseURL !== this._currentRequestURL && redirectedURL !== this._currentRedirectedURL) {\n this._currentRedirectedURL = redirectedURL;\n if (this._onURLRedirect) {\n this._onURLRedirect(redirectedURL);\n }\n }\n }\n\n let lengthHeader = xhr.getResponseHeader('Content-Length');\n if (lengthHeader != null && this._contentLength == null) {\n let length = parseInt(lengthHeader);\n if (length > 0) {\n this._contentLength = length;\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n }\n } else {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});\n } else {\n throw new RuntimeException('MSStreamLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);\n }\n }\n } else if (xhr.readyState === 3) { // LOADING\n if (xhr.status >= 200 && xhr.status <= 299) {\n this._status = LoaderStatus.kBuffering;\n\n let msstream = xhr.response;\n this._reader.readAsArrayBuffer(msstream);\n }\n }\n }\n\n _xhrOnError(e) {\n this._status = LoaderStatus.kError;\n let type = LoaderErrors.EXCEPTION;\n let info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n _msrOnProgress(e) {\n let reader = e.target;\n let bigbuffer = reader.result;\n if (bigbuffer == null) { // result may be null, workaround for buggy M$\n this._doReconnectIfNeeded();\n return;\n }\n\n let slice = bigbuffer.slice(this._lastTimeBufferSize);\n this._lastTimeBufferSize = bigbuffer.byteLength;\n let byteStart = this._totalRange.from + this._receivedLength;\n this._receivedLength += slice.byteLength;\n\n if (this._onDataArrival) {\n this._onDataArrival(slice, byteStart, this._receivedLength);\n }\n\n if (bigbuffer.byteLength >= this._bufferLimit) {\n Log.v(this.TAG, `MSStream buffer exceeded max size near ${byteStart + slice.byteLength}, reconnecting...`);\n this._doReconnectIfNeeded();\n }\n }\n\n _doReconnectIfNeeded() {\n if (this._contentLength == null || this._receivedLength < this._contentLength) {\n this._isReconnecting = true;\n this._lastTimeBufferSize = 0;\n this._internalAbort();\n\n let range = {\n from: this._totalRange.from + this._receivedLength,\n to: -1\n };\n this._internalOpen(this._dataSource, range, true);\n }\n }\n\n _msrOnLoad(e) { // actually it is onComplete event\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._totalRange.from, this._totalRange.from + this._receivedLength - 1);\n }\n }\n\n _msrOnError(e) {\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if (this._contentLength && this._receivedLength < this._contentLength) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: 'MSStream meet Early-Eof'};\n } else {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n}\n\nexport default MSStreamLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport SpeedSampler from './speed-sampler.js';\nimport {BaseLoader, LoaderStatus, LoaderErrors} from './loader.js';\nimport {RuntimeException} from '../utils/exception.js';\n\n// Universal IO Loader, implemented by adding Range header in xhr's request header\nclass RangeLoader extends BaseLoader {\n\n static isSupported() {\n try {\n let xhr = new XMLHttpRequest();\n xhr.open('GET', 'https://example.com', true);\n xhr.responseType = 'arraybuffer';\n return (xhr.responseType === 'arraybuffer');\n } catch (e) {\n Log.w('RangeLoader', e.message);\n return false;\n }\n }\n\n constructor(seekHandler, config) {\n super('xhr-range-loader');\n this.TAG = 'RangeLoader';\n\n this._seekHandler = seekHandler;\n this._config = config;\n this._needStash = false;\n\n this._chunkSizeKBList = [\n 128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192\n ];\n this._currentChunkSizeKB = 384;\n this._currentSpeedNormalized = 0;\n this._zeroSpeedChunkCount = 0;\n\n this._xhr = null;\n this._speedSampler = new SpeedSampler();\n\n this._requestAbort = false;\n this._waitForTotalLength = false;\n this._totalLengthReceived = false;\n\n this._currentRequestURL = null;\n this._currentRedirectedURL = null;\n this._currentRequestRange = null;\n this._totalLength = null; // size of the entire file\n this._contentLength = null; // Content-Length of entire request range\n this._receivedLength = 0; // total received bytes\n this._lastTimeLoaded = 0; // received bytes of current request sub-range\n }\n\n destroy() {\n if (this.isWorking()) {\n this.abort();\n }\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr.onprogress = null;\n this._xhr.onload = null;\n this._xhr.onerror = null;\n this._xhr = null;\n }\n super.destroy();\n }\n\n get currentSpeed() {\n return this._speedSampler.lastSecondKBps;\n }\n\n open(dataSource, range) {\n this._dataSource = dataSource;\n this._range = range;\n this._status = LoaderStatus.kConnecting;\n\n let useRefTotalLength = false;\n if (this._dataSource.filesize != undefined && this._dataSource.filesize !== 0) {\n useRefTotalLength = true;\n this._totalLength = this._dataSource.filesize;\n }\n\n if (!this._totalLengthReceived && !useRefTotalLength) {\n // We need total filesize\n this._waitForTotalLength = true;\n this._internalOpen(this._dataSource, {from: 0, to: -1});\n } else {\n // We have filesize, start loading\n this._openSubRange();\n }\n }\n\n _openSubRange() {\n let chunkSize = this._currentChunkSizeKB * 1024;\n\n let from = this._range.from + this._receivedLength;\n let to = from + chunkSize;\n\n if (this._contentLength != null) {\n if (to - this._range.from >= this._contentLength) {\n to = this._range.from + this._contentLength - 1;\n }\n }\n\n this._currentRequestRange = {from, to};\n this._internalOpen(this._dataSource, this._currentRequestRange);\n }\n\n _internalOpen(dataSource, range) {\n this._lastTimeLoaded = 0;\n\n let sourceURL = dataSource.url;\n if (this._config.reuseRedirectedURL) {\n if (this._currentRedirectedURL != undefined) {\n sourceURL = this._currentRedirectedURL;\n } else if (dataSource.redirectedURL != undefined) {\n sourceURL = dataSource.redirectedURL;\n }\n }\n\n let seekConfig = this._seekHandler.getConfig(sourceURL, range);\n this._currentRequestURL = seekConfig.url;\n\n let xhr = this._xhr = new XMLHttpRequest();\n xhr.open('GET', seekConfig.url, true);\n xhr.responseType = 'arraybuffer';\n xhr.onreadystatechange = this._onReadyStateChange.bind(this);\n xhr.onprogress = this._onProgress.bind(this);\n xhr.onload = this._onLoad.bind(this);\n xhr.onerror = this._onXhrError.bind(this);\n\n if (dataSource.withCredentials && xhr['withCredentials']) {\n xhr.withCredentials = true;\n }\n\n if (typeof seekConfig.headers === 'object') {\n let headers = seekConfig.headers;\n\n for (let key in headers) {\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key]);\n }\n }\n }\n\n xhr.send();\n }\n\n abort() {\n this._requestAbort = true;\n this._internalAbort();\n this._status = LoaderStatus.kComplete;\n }\n\n _internalAbort() {\n if (this._xhr) {\n this._xhr.onreadystatechange = null;\n this._xhr.onprogress = null;\n this._xhr.onload = null;\n this._xhr.onerror = null;\n this._xhr.abort();\n this._xhr = null;\n }\n }\n\n _onReadyStateChange(e) {\n let xhr = e.target;\n\n if (xhr.readyState === 2) { // HEADERS_RECEIVED\n if (xhr.responseURL != undefined) { // if the browser support this property\n let redirectedURL = this._seekHandler.removeURLParameters(xhr.responseURL);\n if (xhr.responseURL !== this._currentRequestURL && redirectedURL !== this._currentRedirectedURL) {\n this._currentRedirectedURL = redirectedURL;\n if (this._onURLRedirect) {\n this._onURLRedirect(redirectedURL);\n }\n }\n }\n\n if ((xhr.status >= 200 && xhr.status <= 299)) {\n if (this._waitForTotalLength) {\n return;\n }\n this._status = LoaderStatus.kBuffering;\n } else {\n this._status = LoaderStatus.kError;\n if (this._onError) {\n this._onError(LoaderErrors.HTTP_STATUS_CODE_INVALID, {code: xhr.status, msg: xhr.statusText});\n } else {\n throw new RuntimeException('RangeLoader: Http code invalid, ' + xhr.status + ' ' + xhr.statusText);\n }\n }\n }\n }\n\n _onProgress(e) {\n if (this._status === LoaderStatus.kError) {\n // Ignore error response\n return;\n }\n\n if (this._contentLength === null) {\n let openNextRange = false;\n\n if (this._waitForTotalLength) {\n this._waitForTotalLength = false;\n this._totalLengthReceived = true;\n openNextRange = true;\n\n let total = e.total;\n this._internalAbort();\n if (total != null & total !== 0) {\n this._totalLength = total;\n }\n }\n\n // calculate currrent request range's contentLength\n if (this._range.to === -1) {\n this._contentLength = this._totalLength - this._range.from;\n } else { // to !== -1\n this._contentLength = this._range.to - this._range.from + 1;\n }\n\n if (openNextRange) {\n this._openSubRange();\n return;\n }\n if (this._onContentLengthKnown) {\n this._onContentLengthKnown(this._contentLength);\n }\n }\n\n let delta = e.loaded - this._lastTimeLoaded;\n this._lastTimeLoaded = e.loaded;\n this._speedSampler.addBytes(delta);\n }\n\n _normalizeSpeed(input) {\n let list = this._chunkSizeKBList;\n let last = list.length - 1;\n let mid = 0;\n let lbound = 0;\n let ubound = last;\n\n if (input < list[0]) {\n return list[0];\n }\n\n while (lbound <= ubound) {\n mid = lbound + Math.floor((ubound - lbound) / 2);\n if (mid === last || (input >= list[mid] && input < list[mid + 1])) {\n return list[mid];\n } else if (list[mid] < input) {\n lbound = mid + 1;\n } else {\n ubound = mid - 1;\n }\n }\n }\n\n _onLoad(e) {\n if (this._status === LoaderStatus.kError) {\n // Ignore error response\n return;\n }\n\n if (this._waitForTotalLength) {\n this._waitForTotalLength = false;\n return;\n }\n\n this._lastTimeLoaded = 0;\n let KBps = this._speedSampler.lastSecondKBps;\n if (KBps === 0) {\n this._zeroSpeedChunkCount++;\n if (this._zeroSpeedChunkCount >= 3) {\n // Try get currentKBps after 3 chunks\n KBps = this._speedSampler.currentKBps;\n }\n }\n\n if (KBps !== 0) {\n let normalized = this._normalizeSpeed(KBps);\n if (this._currentSpeedNormalized !== normalized) {\n this._currentSpeedNormalized = normalized;\n this._currentChunkSizeKB = normalized;\n }\n }\n\n let chunk = e.target.response;\n let byteStart = this._range.from + this._receivedLength;\n this._receivedLength += chunk.byteLength;\n\n let reportComplete = false;\n\n if (this._contentLength != null && this._receivedLength < this._contentLength) {\n // continue load next chunk\n this._openSubRange();\n } else {\n reportComplete = true;\n }\n\n // dispatch received chunk\n if (this._onDataArrival) {\n this._onDataArrival(chunk, byteStart, this._receivedLength);\n }\n\n if (reportComplete) {\n this._status = LoaderStatus.kComplete;\n if (this._onComplete) {\n this._onComplete(this._range.from, this._range.from + this._receivedLength - 1);\n }\n }\n }\n\n _onXhrError(e) {\n this._status = LoaderStatus.kError;\n let type = 0;\n let info = null;\n\n if (this._contentLength && this._receivedLength > 0\n && this._receivedLength < this._contentLength) {\n type = LoaderErrors.EARLY_EOF;\n info = {code: -1, msg: 'RangeLoader meet Early-Eof'};\n } else {\n type = LoaderErrors.EXCEPTION;\n info = {code: -1, msg: e.constructor.name + ' ' + e.type};\n }\n\n if (this._onError) {\n this._onError(type, info);\n } else {\n throw new RuntimeException(info.msg);\n }\n }\n\n}\n\nexport default RangeLoader;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from '../utils/logger.js';\nimport Browser from '../utils/browser.js';\nimport PlayerEvents from './player-events.js';\nimport Transmuxer from '../core/transmuxer.js';\nimport TransmuxingEvents from '../core/transmuxing-events.js';\nimport MSEController from '../core/mse-controller.js';\nimport MSEEvents from '../core/mse-events.js';\nimport {ErrorTypes, ErrorDetails} from './player-errors.js';\nimport {createDefaultConfig} from '../config.js';\nimport {InvalidArgumentException, IllegalStateException} from '../utils/exception.js';\n\nclass FlvPlayer {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'FlvPlayer';\n this._type = 'FlvPlayer';\n this._emitter = new EventEmitter();\n\n this._config = createDefaultConfig();\n if (typeof config === 'object') {\n Object.assign(this._config, config);\n }\n\n if (mediaDataSource.type.toLowerCase() !== 'flv') {\n throw new InvalidArgumentException('FlvPlayer requires an flv MediaDataSource input!');\n }\n\n if (mediaDataSource.isLive === true) {\n this._config.isLive = true;\n }\n\n this.e = {\n onvLoadedMetadata: this._onvLoadedMetadata.bind(this),\n onvSeeking: this._onvSeeking.bind(this),\n onvCanPlay: this._onvCanPlay.bind(this),\n onvStalled: this._onvStalled.bind(this),\n onvProgress: this._onvProgress.bind(this)\n };\n\n if (self.performance && self.performance.now) {\n this._now = self.performance.now.bind(self.performance);\n } else {\n this._now = Date.now;\n }\n\n this._pendingSeekTime = null; // in seconds\n this._requestSetTime = false;\n this._seekpointRecord = null;\n this._progressChecker = null;\n\n this._mediaDataSource = mediaDataSource;\n this._mediaElement = null;\n this._msectl = null;\n this._transmuxer = null;\n\n this._mseSourceOpened = false;\n this._hasPendingLoad = false;\n this._receivedCanPlay = false;\n\n this._mediaInfo = null;\n this._statisticsInfo = null;\n\n let chromeNeedIDRFix = (Browser.chrome &&\n (Browser.version.major < 50 ||\n (Browser.version.major === 50 && Browser.version.build < 2661)));\n this._alwaysSeekKeyframe = (chromeNeedIDRFix || Browser.msedge || Browser.msie) ? true : false;\n\n if (this._alwaysSeekKeyframe) {\n this._config.accurateSeek = false;\n }\n }\n\n destroy() {\n if (this._progressChecker != null) {\n window.clearInterval(this._progressChecker);\n this._progressChecker = null;\n }\n if (this._transmuxer) {\n this.unload();\n }\n if (this._mediaElement) {\n this.detachMediaElement();\n }\n this.e = null;\n this._mediaDataSource = null;\n\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n if (event === PlayerEvents.MEDIA_INFO) {\n if (this._mediaInfo != null) {\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.MEDIA_INFO, this.mediaInfo);\n });\n }\n } else if (event === PlayerEvents.STATISTICS_INFO) {\n if (this._statisticsInfo != null) {\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, this.statisticsInfo);\n });\n }\n }\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n attachMediaElement(mediaElement) {\n this._mediaElement = mediaElement;\n mediaElement.addEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n mediaElement.addEventListener('seeking', this.e.onvSeeking);\n mediaElement.addEventListener('canplay', this.e.onvCanPlay);\n mediaElement.addEventListener('stalled', this.e.onvStalled);\n mediaElement.addEventListener('progress', this.e.onvProgress);\n\n this._msectl = new MSEController(this._config);\n\n this._msectl.on(MSEEvents.UPDATE_END, this._onmseUpdateEnd.bind(this));\n this._msectl.on(MSEEvents.BUFFER_FULL, this._onmseBufferFull.bind(this));\n this._msectl.on(MSEEvents.SOURCE_OPEN, () => {\n this._mseSourceOpened = true;\n if (this._hasPendingLoad) {\n this._hasPendingLoad = false;\n this.load();\n }\n });\n this._msectl.on(MSEEvents.ERROR, (info) => {\n this._emitter.emit(PlayerEvents.ERROR,\n ErrorTypes.MEDIA_ERROR,\n ErrorDetails.MEDIA_MSE_ERROR,\n info\n );\n });\n\n this._msectl.attachMediaElement(mediaElement);\n\n if (this._pendingSeekTime != null) {\n try {\n mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n } catch (e) {\n // IE11 may throw InvalidStateError if readyState === 0\n // We can defer set currentTime operation after loadedmetadata\n }\n }\n }\n\n detachMediaElement() {\n if (this._mediaElement) {\n this._msectl.detachMediaElement();\n this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n this._mediaElement.removeEventListener('seeking', this.e.onvSeeking);\n this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);\n this._mediaElement.removeEventListener('stalled', this.e.onvStalled);\n this._mediaElement.removeEventListener('progress', this.e.onvProgress);\n this._mediaElement = null;\n }\n if (this._msectl) {\n this._msectl.destroy();\n this._msectl = null;\n }\n }\n\n load() {\n if (!this._mediaElement) {\n throw new IllegalStateException('HTMLMediaElement must be attached before load()!');\n }\n if (this._transmuxer) {\n throw new IllegalStateException('FlvPlayer.load() has been called, please call unload() first!');\n }\n if (this._hasPendingLoad) {\n return;\n }\n\n if (this._config.deferLoadAfterSourceOpen && this._mseSourceOpened === false) {\n this._hasPendingLoad = true;\n return;\n }\n\n if (this._mediaElement.readyState > 0) {\n this._requestSetTime = true;\n // IE11 may throw InvalidStateError if readyState === 0\n this._mediaElement.currentTime = 0;\n }\n\n this._transmuxer = new Transmuxer(this._mediaDataSource, this._config);\n\n this._transmuxer.on(TransmuxingEvents.INIT_SEGMENT, (type, is) => {\n this._msectl.appendInitSegment(is);\n });\n this._transmuxer.on(TransmuxingEvents.MEDIA_SEGMENT, (type, ms) => {\n this._msectl.appendMediaSegment(ms);\n\n // lazyLoad check\n if (this._config.lazyLoad && !this._config.isLive) {\n let currentTime = this._mediaElement.currentTime;\n if (ms.info.endDts >= (currentTime + this._config.lazyLoadMaxDuration) * 1000) {\n if (this._progressChecker == null) {\n Log.v(this.TAG, 'Maximum buffering duration exceeded, suspend transmuxing task');\n this._suspendTransmuxer();\n }\n }\n }\n });\n this._transmuxer.on(TransmuxingEvents.LOADING_COMPLETE, () => {\n this._msectl.endOfStream();\n this._emitter.emit(PlayerEvents.LOADING_COMPLETE);\n });\n this._transmuxer.on(TransmuxingEvents.RECOVERED_EARLY_EOF, () => {\n this._emitter.emit(PlayerEvents.RECOVERED_EARLY_EOF);\n });\n this._transmuxer.on(TransmuxingEvents.IO_ERROR, (detail, info) => {\n this._emitter.emit(PlayerEvents.ERROR, ErrorTypes.NETWORK_ERROR, detail, info);\n });\n this._transmuxer.on(TransmuxingEvents.DEMUX_ERROR, (detail, info) => {\n this._emitter.emit(PlayerEvents.ERROR, ErrorTypes.MEDIA_ERROR, detail, {code: -1, msg: info});\n });\n this._transmuxer.on(TransmuxingEvents.MEDIA_INFO, (mediaInfo) => {\n this._mediaInfo = mediaInfo;\n this._emitter.emit(PlayerEvents.MEDIA_INFO, Object.assign({}, mediaInfo));\n });\n this._transmuxer.on(TransmuxingEvents.STATISTICS_INFO, (statInfo) => {\n this._statisticsInfo = this._fillStatisticsInfo(statInfo);\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, Object.assign({}, this._statisticsInfo));\n });\n this._transmuxer.on(TransmuxingEvents.RECOMMEND_SEEKPOINT, (milliseconds) => {\n if (this._mediaElement && !this._config.accurateSeek) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = milliseconds / 1000;\n }\n });\n\n this._transmuxer.open();\n }\n\n unload() {\n if (this._mediaElement) {\n this._mediaElement.pause();\n }\n if (this._msectl) {\n this._msectl.seek(0);\n }\n if (this._transmuxer) {\n this._transmuxer.close();\n this._transmuxer.destroy();\n this._transmuxer = null;\n }\n }\n\n play() {\n return this._mediaElement.play();\n }\n\n pause() {\n this._mediaElement.pause();\n }\n\n get type() {\n return this._type;\n }\n\n get buffered() {\n return this._mediaElement.buffered;\n }\n\n get duration() {\n return this._mediaElement.duration;\n }\n\n get volume() {\n return this._mediaElement.volume;\n }\n\n set volume(value) {\n this._mediaElement.volume = value;\n }\n\n get muted() {\n return this._mediaElement.muted;\n }\n\n set muted(muted) {\n this._mediaElement.muted = muted;\n }\n\n get currentTime() {\n if (this._mediaElement) {\n return this._mediaElement.currentTime;\n }\n return 0;\n }\n\n set currentTime(seconds) {\n if (this._mediaElement) {\n this._internalSeek(seconds);\n } else {\n this._pendingSeekTime = seconds;\n }\n }\n\n get mediaInfo() {\n return Object.assign({}, this._mediaInfo);\n }\n\n get statisticsInfo() {\n if (this._statisticsInfo == null) {\n this._statisticsInfo = {};\n }\n this._statisticsInfo = this._fillStatisticsInfo(this._statisticsInfo);\n return Object.assign({}, this._statisticsInfo);\n }\n\n _fillStatisticsInfo(statInfo) {\n statInfo.playerType = this._type;\n\n if (!(this._mediaElement instanceof HTMLVideoElement)) {\n return statInfo;\n }\n\n let hasQualityInfo = true;\n let decoded = 0;\n let dropped = 0;\n\n if (this._mediaElement.getVideoPlaybackQuality) {\n let quality = this._mediaElement.getVideoPlaybackQuality();\n decoded = quality.totalVideoFrames;\n dropped = quality.droppedVideoFrames;\n } else if (this._mediaElement.webkitDecodedFrameCount != undefined) {\n decoded = this._mediaElement.webkitDecodedFrameCount;\n dropped = this._mediaElement.webkitDroppedFrameCount;\n } else {\n hasQualityInfo = false;\n }\n\n if (hasQualityInfo) {\n statInfo.decodedFrames = decoded;\n statInfo.droppedFrames = dropped;\n }\n\n return statInfo;\n }\n\n _onmseUpdateEnd() {\n if (!this._config.lazyLoad || this._config.isLive) {\n return;\n }\n\n let buffered = this._mediaElement.buffered;\n let currentTime = this._mediaElement.currentTime;\n let currentRangeStart = 0;\n let currentRangeEnd = 0;\n\n for (let i = 0; i < buffered.length; i++) {\n let start = buffered.start(i);\n let end = buffered.end(i);\n if (start <= currentTime && currentTime < end) {\n currentRangeStart = start;\n currentRangeEnd = end;\n break;\n }\n }\n\n if (currentRangeEnd >= currentTime + this._config.lazyLoadMaxDuration && this._progressChecker == null) {\n Log.v(this.TAG, 'Maximum buffering duration exceeded, suspend transmuxing task');\n this._suspendTransmuxer();\n }\n }\n\n _onmseBufferFull() {\n Log.v(this.TAG, 'MSE SourceBuffer is full, suspend transmuxing task');\n if (this._progressChecker == null) {\n this._suspendTransmuxer();\n }\n }\n\n _suspendTransmuxer() {\n if (this._transmuxer) {\n this._transmuxer.pause();\n\n if (this._progressChecker == null) {\n this._progressChecker = window.setInterval(this._checkProgressAndResume.bind(this), 1000);\n }\n }\n }\n\n _checkProgressAndResume() {\n let currentTime = this._mediaElement.currentTime;\n let buffered = this._mediaElement.buffered;\n\n let needResume = false;\n\n for (let i = 0; i < buffered.length; i++) {\n let from = buffered.start(i);\n let to = buffered.end(i);\n if (currentTime >= from && currentTime < to) {\n if (currentTime >= to - this._config.lazyLoadRecoverDuration) {\n needResume = true;\n }\n break;\n }\n }\n\n if (needResume) {\n window.clearInterval(this._progressChecker);\n this._progressChecker = null;\n if (needResume) {\n Log.v(this.TAG, 'Continue loading from paused position');\n this._transmuxer.resume();\n }\n }\n }\n\n _isTimepointBuffered(seconds) {\n let buffered = this._mediaElement.buffered;\n\n for (let i = 0; i < buffered.length; i++) {\n let from = buffered.start(i);\n let to = buffered.end(i);\n if (seconds >= from && seconds < to) {\n return true;\n }\n }\n return false;\n }\n\n _internalSeek(seconds) {\n let directSeek = this._isTimepointBuffered(seconds);\n\n let directSeekBegin = false;\n let directSeekBeginTime = 0;\n\n if (seconds < 1.0 && this._mediaElement.buffered.length > 0) {\n let videoBeginTime = this._mediaElement.buffered.start(0);\n if ((videoBeginTime < 1.0 && seconds < videoBeginTime) || Browser.safari) {\n directSeekBegin = true;\n // also workaround for Safari: Seek to 0 may cause video stuck, use 0.1 to avoid\n directSeekBeginTime = Browser.safari ? 0.1 : videoBeginTime;\n }\n }\n\n if (directSeekBegin) { // seek to video begin, set currentTime directly if beginPTS buffered\n this._requestSetTime = true;\n this._mediaElement.currentTime = directSeekBeginTime;\n } else if (directSeek) { // buffered position\n if (!this._alwaysSeekKeyframe) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = seconds;\n } else {\n let idr = this._msectl.getNearestKeyframe(Math.floor(seconds * 1000));\n this._requestSetTime = true;\n if (idr != null) {\n this._mediaElement.currentTime = idr.dts / 1000;\n } else {\n this._mediaElement.currentTime = seconds;\n }\n }\n if (this._progressChecker != null) {\n this._checkProgressAndResume();\n }\n } else {\n if (this._progressChecker != null) {\n window.clearInterval(this._progressChecker);\n this._progressChecker = null;\n }\n this._msectl.seek(seconds);\n this._transmuxer.seek(Math.floor(seconds * 1000)); // in milliseconds\n // no need to set mediaElement.currentTime if non-accurateSeek,\n // just wait for the recommend_seekpoint callback\n if (this._config.accurateSeek) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = seconds;\n }\n }\n }\n\n _checkAndApplyUnbufferedSeekpoint() {\n if (this._seekpointRecord) {\n if (this._seekpointRecord.recordTime <= this._now() - 100) {\n let target = this._mediaElement.currentTime;\n this._seekpointRecord = null;\n if (!this._isTimepointBuffered(target)) {\n if (this._progressChecker != null) {\n window.clearTimeout(this._progressChecker);\n this._progressChecker = null;\n }\n // .currentTime is consists with .buffered timestamp\n // Chrome/Edge use DTS, while FireFox/Safari use PTS\n this._msectl.seek(target);\n this._transmuxer.seek(Math.floor(target * 1000));\n // set currentTime if accurateSeek, or wait for recommend_seekpoint callback\n if (this._config.accurateSeek) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = target;\n }\n }\n } else {\n window.setTimeout(this._checkAndApplyUnbufferedSeekpoint.bind(this), 50);\n }\n }\n }\n\n _checkAndResumeStuckPlayback(stalled) {\n let media = this._mediaElement;\n if (stalled || !this._receivedCanPlay || media.readyState < 2) { // HAVE_CURRENT_DATA\n let buffered = media.buffered;\n if (buffered.length > 0 && media.currentTime < buffered.start(0)) {\n Log.w(this.TAG, `Playback seems stuck at ${media.currentTime}, seek to ${buffered.start(0)}`);\n this._requestSetTime = true;\n this._mediaElement.currentTime = buffered.start(0);\n this._mediaElement.removeEventListener('progress', this.e.onvProgress);\n }\n } else {\n // Playback didn't stuck, remove progress event listener\n this._mediaElement.removeEventListener('progress', this.e.onvProgress);\n }\n }\n\n _onvLoadedMetadata(e) {\n if (this._pendingSeekTime != null) {\n this._mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n }\n }\n\n _onvSeeking(e) { // handle seeking request from browser's progress bar\n let target = this._mediaElement.currentTime;\n let buffered = this._mediaElement.buffered;\n\n if (this._requestSetTime) {\n this._requestSetTime = false;\n return;\n }\n\n if (target < 1.0 && buffered.length > 0) {\n // seek to video begin, set currentTime directly if beginPTS buffered\n let videoBeginTime = buffered.start(0);\n if ((videoBeginTime < 1.0 && target < videoBeginTime) || Browser.safari) {\n this._requestSetTime = true;\n // also workaround for Safari: Seek to 0 may cause video stuck, use 0.1 to avoid\n this._mediaElement.currentTime = Browser.safari ? 0.1 : videoBeginTime;\n return;\n }\n }\n\n if (this._isTimepointBuffered(target)) {\n if (this._alwaysSeekKeyframe) {\n let idr = this._msectl.getNearestKeyframe(Math.floor(target * 1000));\n if (idr != null) {\n this._requestSetTime = true;\n this._mediaElement.currentTime = idr.dts / 1000;\n }\n }\n if (this._progressChecker != null) {\n this._checkProgressAndResume();\n }\n return;\n }\n\n this._seekpointRecord = {\n seekPoint: target,\n recordTime: this._now()\n };\n window.setTimeout(this._checkAndApplyUnbufferedSeekpoint.bind(this), 50);\n }\n\n _onvCanPlay(e) {\n this._receivedCanPlay = true;\n this._mediaElement.removeEventListener('canplay', this.e.onvCanPlay);\n }\n\n _onvStalled(e) {\n this._checkAndResumeStuckPlayback(true);\n }\n\n _onvProgress(e) {\n this._checkAndResumeStuckPlayback();\n }\n\n}\n\nexport default FlvPlayer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport PlayerEvents from './player-events.js';\nimport {createDefaultConfig} from '../config.js';\nimport {InvalidArgumentException, IllegalStateException} from '../utils/exception.js';\n\n// Player wrapper for browser's native player (HTMLVideoElement) without MediaSource src. \nclass NativePlayer {\n\n constructor(mediaDataSource, config) {\n this.TAG = 'NativePlayer';\n this._type = 'NativePlayer';\n this._emitter = new EventEmitter();\n\n this._config = createDefaultConfig();\n if (typeof config === 'object') {\n Object.assign(this._config, config);\n }\n\n if (mediaDataSource.type.toLowerCase() === 'flv') {\n throw new InvalidArgumentException('NativePlayer does\\'t support flv MediaDataSource input!');\n }\n if (mediaDataSource.hasOwnProperty('segments')) {\n throw new InvalidArgumentException(`NativePlayer(${mediaDataSource.type}) doesn't support multipart playback!`);\n }\n\n this.e = {\n onvLoadedMetadata: this._onvLoadedMetadata.bind(this)\n };\n\n this._pendingSeekTime = null;\n this._statisticsReporter = null;\n\n this._mediaDataSource = mediaDataSource;\n this._mediaElement = null;\n }\n\n destroy() {\n if (this._mediaElement) {\n this.unload();\n this.detachMediaElement();\n }\n this.e = null;\n this._mediaDataSource = null;\n this._emitter.removeAllListeners();\n this._emitter = null;\n }\n\n on(event, listener) {\n if (event === PlayerEvents.MEDIA_INFO) {\n if (this._mediaElement != null && this._mediaElement.readyState !== 0) { // HAVE_NOTHING\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.MEDIA_INFO, this.mediaInfo);\n });\n }\n } else if (event === PlayerEvents.STATISTICS_INFO) {\n if (this._mediaElement != null && this._mediaElement.readyState !== 0) {\n Promise.resolve().then(() => {\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, this.statisticsInfo);\n });\n }\n }\n this._emitter.addListener(event, listener);\n }\n\n off(event, listener) {\n this._emitter.removeListener(event, listener);\n }\n\n attachMediaElement(mediaElement) {\n this._mediaElement = mediaElement;\n mediaElement.addEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n\n if (this._pendingSeekTime != null) {\n try {\n mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n } catch (e) {\n // IE11 may throw InvalidStateError if readyState === 0\n // Defer set currentTime operation after loadedmetadata\n }\n }\n }\n\n detachMediaElement() {\n if (this._mediaElement) {\n this._mediaElement.src = '';\n this._mediaElement.removeAttribute('src');\n this._mediaElement.removeEventListener('loadedmetadata', this.e.onvLoadedMetadata);\n this._mediaElement = null;\n }\n if (this._statisticsReporter != null) {\n window.clearInterval(this._statisticsReporter);\n this._statisticsReporter = null;\n }\n }\n\n load() {\n if (!this._mediaElement) {\n throw new IllegalStateException('HTMLMediaElement must be attached before load()!');\n }\n this._mediaElement.src = this._mediaDataSource.url;\n\n if (this._mediaElement.readyState > 0) {\n this._mediaElement.currentTime = 0;\n }\n\n this._mediaElement.preload = 'auto';\n this._mediaElement.load();\n this._statisticsReporter = window.setInterval(\n this._reportStatisticsInfo.bind(this),\n this._config.statisticsInfoReportInterval);\n }\n\n unload() {\n if (this._mediaElement) {\n this._mediaElement.src = '';\n this._mediaElement.removeAttribute('src');\n }\n if (this._statisticsReporter != null) {\n window.clearInterval(this._statisticsReporter);\n this._statisticsReporter = null;\n }\n }\n\n play() {\n return this._mediaElement.play();\n }\n\n pause() {\n this._mediaElement.pause();\n }\n\n get type() {\n return this._type;\n }\n\n get buffered() {\n return this._mediaElement.buffered;\n }\n\n get duration() {\n return this._mediaElement.duration;\n }\n\n get volume() {\n return this._mediaElement.volume;\n }\n\n set volume(value) {\n this._mediaElement.volume = value;\n }\n\n get muted() {\n return this._mediaElement.muted;\n }\n\n set muted(muted) {\n this._mediaElement.muted = muted;\n }\n\n get currentTime() {\n if (this._mediaElement) {\n return this._mediaElement.currentTime;\n }\n return 0;\n }\n\n set currentTime(seconds) {\n if (this._mediaElement) {\n this._mediaElement.currentTime = seconds;\n } else {\n this._pendingSeekTime = seconds;\n }\n }\n\n get mediaInfo() {\n let mediaPrefix = (this._mediaElement instanceof HTMLAudioElement) ? 'audio/' : 'video/';\n let info = {\n mimeType: mediaPrefix + this._mediaDataSource.type\n };\n if (this._mediaElement) {\n info.duration = Math.floor(this._mediaElement.duration * 1000);\n if (this._mediaElement instanceof HTMLVideoElement) {\n info.width = this._mediaElement.videoWidth;\n info.height = this._mediaElement.videoHeight;\n }\n }\n return info;\n }\n\n get statisticsInfo() {\n let info = {\n playerType: this._type,\n url: this._mediaDataSource.url\n };\n\n if (!(this._mediaElement instanceof HTMLVideoElement)) {\n return info;\n }\n\n let hasQualityInfo = true;\n let decoded = 0;\n let dropped = 0;\n\n if (this._mediaElement.getVideoPlaybackQuality) {\n let quality = this._mediaElement.getVideoPlaybackQuality();\n decoded = quality.totalVideoFrames;\n dropped = quality.droppedVideoFrames;\n } else if (this._mediaElement.webkitDecodedFrameCount != undefined) {\n decoded = this._mediaElement.webkitDecodedFrameCount;\n dropped = this._mediaElement.webkitDroppedFrameCount;\n } else {\n hasQualityInfo = false;\n }\n\n if (hasQualityInfo) {\n info.decodedFrames = decoded;\n info.droppedFrames = dropped;\n }\n \n return info;\n }\n\n _onvLoadedMetadata(e) {\n if (this._pendingSeekTime != null) {\n this._mediaElement.currentTime = this._pendingSeekTime;\n this._pendingSeekTime = null;\n }\n this._emitter.emit(PlayerEvents.MEDIA_INFO, this.mediaInfo);\n }\n\n _reportStatisticsInfo() {\n this._emitter.emit(PlayerEvents.STATISTICS_INFO, this.statisticsInfo);\n }\n\n}\n\nexport default NativePlayer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {LoaderErrors} from '../io/loader.js';\nimport DemuxErrors from '../demux/demux-errors.js';\n\nexport const ErrorTypes = {\n NETWORK_ERROR: 'NetworkError',\n MEDIA_ERROR: 'MediaError',\n OTHER_ERROR: 'OtherError'\n};\n\nexport const ErrorDetails = {\n NETWORK_EXCEPTION: LoaderErrors.EXCEPTION,\n NETWORK_STATUS_CODE_INVALID: LoaderErrors.HTTP_STATUS_CODE_INVALID,\n NETWORK_TIMEOUT: LoaderErrors.CONNECTING_TIMEOUT,\n NETWORK_UNRECOVERABLE_EARLY_EOF: LoaderErrors.UNRECOVERABLE_EARLY_EOF,\n\n MEDIA_MSE_ERROR: 'MediaMSEError',\n\n MEDIA_FORMAT_ERROR: DemuxErrors.FORMAT_ERROR,\n MEDIA_FORMAT_UNSUPPORTED: DemuxErrors.FORMAT_UNSUPPORTED,\n MEDIA_CODEC_UNSUPPORTED: DemuxErrors.CODEC_UNSUPPORTED\n};","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst PlayerEvents = {\n ERROR: 'error',\n LOADING_COMPLETE: 'loading_complete',\n RECOVERED_EARLY_EOF: 'recovered_early_eof',\n MEDIA_INFO: 'media_info',\n STATISTICS_INFO: 'statistics_info'\n};\n\nexport default PlayerEvents;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * This file is modified from dailymotion's hls.js library (hls.js/src/helper/aac.js)\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass AAC {\n\n static getSilentFrame(codec, channelCount) {\n if (codec === 'mp4a.40.2') {\n // handle LC-AAC\n if (channelCount === 1) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);\n } else if (channelCount === 2) {\n return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]);\n } else if (channelCount === 3) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]);\n } else if (channelCount === 4) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]);\n } else if (channelCount === 5) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]);\n } else if (channelCount === 6) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]);\n }\n } else {\n // handle HE-AAC (mp4a.40.5 / mp4a.40.29)\n if (channelCount === 1) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0:d=0.05\" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);\n } else if (channelCount === 2) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0|0:d=0.05\" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);\n } else if (channelCount === 3) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0|0|0:d=0.05\" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);\n }\n }\n return null;\n }\n\n}\n\nexport default AAC;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * This file is derived from dailymotion's hls.js library (hls.js/src/remux/mp4-generator.js)\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// MP4 boxes generator for ISO BMFF (ISO Base Media File Format, defined in ISO/IEC 14496-12)\nclass MP4 {\n\n static init() {\n MP4.types = {\n avc1: [], avcC: [], btrt: [], dinf: [],\n dref: [], esds: [], ftyp: [], hdlr: [],\n mdat: [], mdhd: [], mdia: [], mfhd: [],\n minf: [], moof: [], moov: [], mp4a: [],\n mvex: [], mvhd: [], sdtp: [], stbl: [],\n stco: [], stsc: [], stsd: [], stsz: [],\n stts: [], tfdt: [], tfhd: [], traf: [],\n trak: [], trun: [], trex: [], tkhd: [],\n vmhd: [], smhd: [], '.mp3': []\n };\n\n for (let name in MP4.types) {\n if (MP4.types.hasOwnProperty(name)) {\n MP4.types[name] = [\n name.charCodeAt(0),\n name.charCodeAt(1),\n name.charCodeAt(2),\n name.charCodeAt(3)\n ];\n }\n }\n\n let constants = MP4.constants = {};\n\n constants.FTYP = new Uint8Array([\n 0x69, 0x73, 0x6F, 0x6D, // major_brand: isom\n 0x0, 0x0, 0x0, 0x1, // minor_version: 0x01\n 0x69, 0x73, 0x6F, 0x6D, // isom\n 0x61, 0x76, 0x63, 0x31 // avc1\n ]);\n\n constants.STSD_PREFIX = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x01 // entry_count\n ]);\n\n constants.STTS = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00 // entry_count\n ]);\n\n constants.STSC = constants.STCO = constants.STTS;\n\n constants.STSZ = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // sample_size\n 0x00, 0x00, 0x00, 0x00 // sample_count\n ]);\n\n constants.HDLR_VIDEO = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // pre_defined\n 0x76, 0x69, 0x64, 0x65, // handler_type: 'vide'\n 0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x56, 0x69, 0x64, 0x65,\n 0x6F, 0x48, 0x61, 0x6E,\n 0x64, 0x6C, 0x65, 0x72, 0x00 // name: VideoHandler\n ]);\n\n constants.HDLR_AUDIO = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // pre_defined\n 0x73, 0x6F, 0x75, 0x6E, // handler_type: 'soun'\n 0x00, 0x00, 0x00, 0x00, // reserved: 3 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x53, 0x6F, 0x75, 0x6E,\n 0x64, 0x48, 0x61, 0x6E,\n 0x64, 0x6C, 0x65, 0x72, 0x00 // name: SoundHandler\n ]);\n\n constants.DREF = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x01, // entry_count\n 0x00, 0x00, 0x00, 0x0C, // entry_size\n 0x75, 0x72, 0x6C, 0x20, // type 'url '\n 0x00, 0x00, 0x00, 0x01 // version(0) + flags\n ]);\n\n // Sound media header\n constants.SMHD = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00 // balance(2) + reserved(2)\n ]);\n\n // video media header\n constants.VMHD = new Uint8Array([\n 0x00, 0x00, 0x00, 0x01, // version(0) + flags\n 0x00, 0x00, // graphicsmode: 2 bytes\n 0x00, 0x00, 0x00, 0x00, // opcolor: 3 * 2 bytes\n 0x00, 0x00\n ]);\n }\n\n // Generate a box\n static box(type) {\n let size = 8;\n let result = null;\n let datas = Array.prototype.slice.call(arguments, 1);\n let arrayCount = datas.length;\n\n for (let i = 0; i < arrayCount; i++) {\n size += datas[i].byteLength;\n }\n\n result = new Uint8Array(size);\n result[0] = (size >>> 24) & 0xFF; // size\n result[1] = (size >>> 16) & 0xFF;\n result[2] = (size >>> 8) & 0xFF;\n result[3] = (size) & 0xFF;\n\n result.set(type, 4); // type\n\n let offset = 8;\n for (let i = 0; i < arrayCount; i++) { // data body\n result.set(datas[i], offset);\n offset += datas[i].byteLength;\n }\n\n return result;\n }\n\n // emit ftyp & moov\n static generateInitSegment(meta) {\n let ftyp = MP4.box(MP4.types.ftyp, MP4.constants.FTYP);\n let moov = MP4.moov(meta);\n\n let result = new Uint8Array(ftyp.byteLength + moov.byteLength);\n result.set(ftyp, 0);\n result.set(moov, ftyp.byteLength);\n return result;\n }\n\n // Movie metadata box\n static moov(meta) {\n let mvhd = MP4.mvhd(meta.timescale, meta.duration);\n let trak = MP4.trak(meta);\n let mvex = MP4.mvex(meta);\n return MP4.box(MP4.types.moov, mvhd, trak, mvex);\n }\n\n // Movie header box\n static mvhd(timescale, duration) {\n return MP4.box(MP4.types.mvhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // creation_time\n 0x00, 0x00, 0x00, 0x00, // modification_time\n (timescale >>> 24) & 0xFF, // timescale: 4 bytes\n (timescale >>> 16) & 0xFF,\n (timescale >>> 8) & 0xFF,\n (timescale) & 0xFF,\n (duration >>> 24) & 0xFF, // duration: 4 bytes\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n 0x00, 0x01, 0x00, 0x00, // Preferred rate: 1.0\n 0x01, 0x00, 0x00, 0x00, // PreferredVolume(1.0, 2bytes) + reserved(2bytes)\n 0x00, 0x00, 0x00, 0x00, // reserved: 4 + 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x01, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x40, 0x00, 0x00, 0x00, // ----end composition matrix----\n 0x00, 0x00, 0x00, 0x00, // ----begin pre_defined 6 * 4 bytes----\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, // ----end pre_defined 6 * 4 bytes----\n 0xFF, 0xFF, 0xFF, 0xFF // next_track_ID\n ]));\n }\n\n // Track box\n static trak(meta) {\n return MP4.box(MP4.types.trak, MP4.tkhd(meta), MP4.mdia(meta));\n }\n\n // Track header box\n static tkhd(meta) {\n let trackId = meta.id, duration = meta.duration;\n let width = meta.presentWidth, height = meta.presentHeight;\n\n return MP4.box(MP4.types.tkhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x07, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // creation_time\n 0x00, 0x00, 0x00, 0x00, // modification_time\n (trackId >>> 24) & 0xFF, // track_ID: 4 bytes\n (trackId >>> 16) & 0xFF,\n (trackId >>> 8) & 0xFF,\n (trackId) & 0xFF,\n 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes\n (duration >>> 24) & 0xFF, // duration: 4 bytes\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, // layer(2bytes) + alternate_group(2bytes)\n 0x00, 0x00, 0x00, 0x00, // volume(2bytes) + reserved(2bytes)\n 0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x01, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x40, 0x00, 0x00, 0x00, // ----end composition matrix----\n (width >>> 8) & 0xFF, // width and height\n (width) & 0xFF,\n 0x00, 0x00,\n (height >>> 8) & 0xFF,\n (height) & 0xFF,\n 0x00, 0x00\n ]));\n }\n\n // Media Box\n static mdia(meta) {\n return MP4.box(MP4.types.mdia, MP4.mdhd(meta), MP4.hdlr(meta), MP4.minf(meta));\n }\n\n // Media header box\n static mdhd(meta) {\n let timescale = meta.timescale;\n let duration = meta.duration;\n return MP4.box(MP4.types.mdhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n 0x00, 0x00, 0x00, 0x00, // creation_time\n 0x00, 0x00, 0x00, 0x00, // modification_time\n (timescale >>> 24) & 0xFF, // timescale: 4 bytes\n (timescale >>> 16) & 0xFF,\n (timescale >>> 8) & 0xFF,\n (timescale) & 0xFF,\n (duration >>> 24) & 0xFF, // duration: 4 bytes\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n 0x55, 0xC4, // language: und (undetermined)\n 0x00, 0x00 // pre_defined = 0\n ]));\n }\n\n // Media handler reference box\n static hdlr(meta) {\n let data = null;\n if (meta.type === 'audio') {\n data = MP4.constants.HDLR_AUDIO;\n } else {\n data = MP4.constants.HDLR_VIDEO;\n }\n return MP4.box(MP4.types.hdlr, data);\n }\n\n // Media infomation box\n static minf(meta) {\n let xmhd = null;\n if (meta.type === 'audio') {\n xmhd = MP4.box(MP4.types.smhd, MP4.constants.SMHD);\n } else {\n xmhd = MP4.box(MP4.types.vmhd, MP4.constants.VMHD);\n }\n return MP4.box(MP4.types.minf, xmhd, MP4.dinf(), MP4.stbl(meta));\n }\n\n // Data infomation box\n static dinf() {\n let result = MP4.box(MP4.types.dinf,\n MP4.box(MP4.types.dref, MP4.constants.DREF)\n );\n return result;\n }\n\n // Sample table box\n static stbl(meta) {\n let result = MP4.box(MP4.types.stbl, // type: stbl\n MP4.stsd(meta), // Sample Description Table\n MP4.box(MP4.types.stts, MP4.constants.STTS), // Time-To-Sample\n MP4.box(MP4.types.stsc, MP4.constants.STSC), // Sample-To-Chunk\n MP4.box(MP4.types.stsz, MP4.constants.STSZ), // Sample size\n MP4.box(MP4.types.stco, MP4.constants.STCO) // Chunk offset\n ); \n return result; \n }\n\n // Sample description box\n static stsd(meta) {\n if (meta.type === 'audio') {\n if (meta.codec === 'mp3') {\n return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp3(meta));\n }\n // else: aac -> mp4a\n return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.mp4a(meta));\n } else {\n return MP4.box(MP4.types.stsd, MP4.constants.STSD_PREFIX, MP4.avc1(meta));\n }\n }\n\n static mp3(meta) {\n let channelCount = meta.channelCount;\n let sampleRate = meta.audioSampleRate;\n\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)\n 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, channelCount, // channelCount(2)\n 0x00, 0x10, // sampleSize(2)\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n (sampleRate >>> 8) & 0xFF, // Audio sample rate\n (sampleRate) & 0xFF,\n 0x00, 0x00\n ]);\n\n return MP4.box(MP4.types['.mp3'], data);\n }\n\n static mp4a(meta) {\n let channelCount = meta.channelCount;\n let sampleRate = meta.audioSampleRate;\n\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)\n 0x00, 0x00, 0x00, 0x00, // reserved: 2 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, channelCount, // channelCount(2)\n 0x00, 0x10, // sampleSize(2)\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n (sampleRate >>> 8) & 0xFF, // Audio sample rate\n (sampleRate) & 0xFF,\n 0x00, 0x00\n ]);\n\n return MP4.box(MP4.types.mp4a, data, MP4.esds(meta));\n }\n\n static esds(meta) {\n let config = meta.config || [];\n let configSize = config.length;\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version 0 + flags\n\n 0x03, // descriptor_type\n 0x17 + configSize, // length3\n 0x00, 0x01, // es_id\n 0x00, // stream_priority\n\n 0x04, // descriptor_type\n 0x0F + configSize, // length\n 0x40, // codec: mpeg4_audio\n 0x15, // stream_type: Audio\n 0x00, 0x00, 0x00, // buffer_size\n 0x00, 0x00, 0x00, 0x00, // maxBitrate\n 0x00, 0x00, 0x00, 0x00, // avgBitrate\n\n 0x05 // descriptor_type\n ].concat([\n configSize\n ]).concat(\n config\n ).concat([\n 0x06, 0x01, 0x02 // GASpecificConfig\n ]));\n return MP4.box(MP4.types.esds, data);\n }\n\n static avc1(meta) {\n let avcc = meta.avcc;\n let width = meta.codecWidth, height = meta.codecHeight;\n\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // reserved(4)\n 0x00, 0x00, 0x00, 0x01, // reserved(2) + data_reference_index(2)\n 0x00, 0x00, 0x00, 0x00, // pre_defined(2) + reserved(2)\n 0x00, 0x00, 0x00, 0x00, // pre_defined: 3 * 4 bytes\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n (width >>> 8) & 0xFF, // width: 2 bytes\n (width) & 0xFF,\n (height >>> 8) & 0xFF, // height: 2 bytes\n (height) & 0xFF,\n 0x00, 0x48, 0x00, 0x00, // horizresolution: 4 bytes\n 0x00, 0x48, 0x00, 0x00, // vertresolution: 4 bytes\n 0x00, 0x00, 0x00, 0x00, // reserved: 4 bytes\n 0x00, 0x01, // frame_count\n 0x0A, // strlen\n 0x78, 0x71, 0x71, 0x2F, // compressorname: 32 bytes\n 0x66, 0x6C, 0x76, 0x2E,\n 0x6A, 0x73, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00,\n 0x00, 0x18, // depth\n 0xFF, 0xFF // pre_defined = -1\n ]);\n return MP4.box(MP4.types.avc1, data, MP4.box(MP4.types.avcC, avcc));\n }\n\n // Movie Extends box\n static mvex(meta) {\n return MP4.box(MP4.types.mvex, MP4.trex(meta));\n }\n\n // Track Extends box\n static trex(meta) {\n let trackId = meta.id;\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) + flags\n (trackId >>> 24) & 0xFF, // track_ID\n (trackId >>> 16) & 0xFF,\n (trackId >>> 8) & 0xFF,\n (trackId) & 0xFF,\n 0x00, 0x00, 0x00, 0x01, // default_sample_description_index\n 0x00, 0x00, 0x00, 0x00, // default_sample_duration\n 0x00, 0x00, 0x00, 0x00, // default_sample_size\n 0x00, 0x01, 0x00, 0x01 // default_sample_flags\n ]);\n return MP4.box(MP4.types.trex, data);\n }\n\n // Movie fragment box\n static moof(track, baseMediaDecodeTime) {\n return MP4.box(MP4.types.moof, MP4.mfhd(track.sequenceNumber), MP4.traf(track, baseMediaDecodeTime));\n }\n\n static mfhd(sequenceNumber) {\n let data = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00,\n (sequenceNumber >>> 24) & 0xFF, // sequence_number: int32\n (sequenceNumber >>> 16) & 0xFF,\n (sequenceNumber >>> 8) & 0xFF,\n (sequenceNumber) & 0xFF\n ]);\n return MP4.box(MP4.types.mfhd, data);\n }\n\n // Track fragment box\n static traf(track, baseMediaDecodeTime) {\n let trackId = track.id;\n\n // Track fragment header box\n let tfhd = MP4.box(MP4.types.tfhd, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) & flags\n (trackId >>> 24) & 0xFF, // track_ID\n (trackId >>> 16) & 0xFF,\n (trackId >>> 8) & 0xFF,\n (trackId) & 0xFF\n ]));\n // Track Fragment Decode Time\n let tfdt = MP4.box(MP4.types.tfdt, new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // version(0) & flags\n (baseMediaDecodeTime >>> 24) & 0xFF, // baseMediaDecodeTime: int32\n (baseMediaDecodeTime >>> 16) & 0xFF,\n (baseMediaDecodeTime >>> 8) & 0xFF,\n (baseMediaDecodeTime) & 0xFF\n ]));\n let sdtp = MP4.sdtp(track);\n let trun = MP4.trun(track, sdtp.byteLength + 16 + 16 + 8 + 16 + 8 + 8);\n\n return MP4.box(MP4.types.traf, tfhd, tfdt, trun, sdtp);\n }\n\n // Sample Dependency Type box\n static sdtp(track) {\n let samples = track.samples || [];\n let sampleCount = samples.length;\n let data = new Uint8Array(4 + sampleCount);\n // 0~4 bytes: version(0) & flags\n for (let i = 0; i < sampleCount; i++) {\n let flags = samples[i].flags;\n data[i + 4] = (flags.isLeading << 6) // is_leading: 2 (bit)\n | (flags.dependsOn << 4) // sample_depends_on\n | (flags.isDependedOn << 2) // sample_is_depended_on\n | (flags.hasRedundancy); // sample_has_redundancy\n }\n return MP4.box(MP4.types.sdtp, data);\n }\n\n // Track fragment run box\n static trun(track, offset) {\n let samples = track.samples || [];\n let sampleCount = samples.length;\n let dataSize = 12 + 16 * sampleCount;\n let data = new Uint8Array(dataSize);\n offset += 8 + dataSize;\n\n data.set([\n 0x00, 0x00, 0x0F, 0x01, // version(0) & flags\n (sampleCount >>> 24) & 0xFF, // sample_count\n (sampleCount >>> 16) & 0xFF,\n (sampleCount >>> 8) & 0xFF,\n (sampleCount) & 0xFF,\n (offset >>> 24) & 0xFF, // data_offset\n (offset >>> 16) & 0xFF,\n (offset >>> 8) & 0xFF,\n (offset) & 0xFF\n ], 0);\n\n for (let i = 0; i < sampleCount; i++) {\n let duration = samples[i].duration;\n let size = samples[i].size;\n let flags = samples[i].flags;\n let cts = samples[i].cts;\n data.set([\n (duration >>> 24) & 0xFF, // sample_duration\n (duration >>> 16) & 0xFF,\n (duration >>> 8) & 0xFF,\n (duration) & 0xFF,\n (size >>> 24) & 0xFF, // sample_size\n (size >>> 16) & 0xFF,\n (size >>> 8) & 0xFF,\n (size) & 0xFF,\n (flags.isLeading << 2) | flags.dependsOn, // sample_flags\n (flags.isDependedOn << 6) | (flags.hasRedundancy << 4) | flags.isNonSync,\n 0x00, 0x00, // sample_degradation_priority\n (cts >>> 24) & 0xFF, // sample_composition_time_offset\n (cts >>> 16) & 0xFF,\n (cts >>> 8) & 0xFF,\n (cts) & 0xFF\n ], 12 + 16 * i);\n }\n return MP4.box(MP4.types.trun, data);\n }\n\n static mdat(data) {\n return MP4.box(MP4.types.mdat, data);\n }\n\n}\n\nMP4.init();\n\nexport default MP4;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Log from '../utils/logger.js';\nimport MP4 from './mp4-generator.js';\nimport AAC from './aac-silent.js';\nimport Browser from '../utils/browser.js';\nimport {SampleInfo, MediaSegmentInfo, MediaSegmentInfoList} from '../core/media-segment-info.js';\nimport {IllegalStateException} from '../utils/exception.js';\n\n\n// Fragmented mp4 remuxer\nclass MP4Remuxer {\n\n constructor(config) {\n this.TAG = 'MP4Remuxer';\n\n this._config = config;\n this._isLive = (config.isLive === true) ? true : false;\n\n this._dtsBase = -1;\n this._dtsBaseInited = false;\n this._audioDtsBase = Infinity;\n this._videoDtsBase = Infinity;\n this._audioNextDts = undefined;\n this._videoNextDts = undefined;\n\n this._audioMeta = null;\n this._videoMeta = null;\n\n this._audioSegmentInfoList = new MediaSegmentInfoList('audio');\n this._videoSegmentInfoList = new MediaSegmentInfoList('video');\n\n this._onInitSegment = null;\n this._onMediaSegment = null;\n\n // Workaround for chrome < 50: Always force first sample as a Random Access Point in media segment\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412\n this._forceFirstIDR = (Browser.chrome &&\n (Browser.version.major < 50 ||\n (Browser.version.major === 50 && Browser.version.build < 2661))) ? true : false;\n\n // Workaround for IE11/Edge: Fill silent aac frame after keyframe-seeking\n // Make audio beginDts equals with video beginDts, in order to fix seek freeze\n this._fillSilentAfterSeek = (Browser.msedge || Browser.msie);\n\n // While only FireFox supports 'audio/mp4, codecs=\"mp3\"', use 'audio/mpeg' for chrome, safari, ...\n this._mp3UseMpegAudio = !Browser.firefox;\n\n this._fillAudioTimestampGap = this._config.fixAudioTimestampGap;\n }\n\n destroy() {\n this._dtsBase = -1;\n this._dtsBaseInited = false;\n this._audioMeta = null;\n this._videoMeta = null;\n this._audioSegmentInfoList.clear();\n this._audioSegmentInfoList = null;\n this._videoSegmentInfoList.clear();\n this._videoSegmentInfoList = null;\n this._onInitSegment = null;\n this._onMediaSegment = null;\n }\n\n bindDataSource(producer) {\n producer.onDataAvailable = this.remux.bind(this);\n producer.onTrackMetadata = this._onTrackMetadataReceived.bind(this);\n return this;\n }\n\n /* prototype: function onInitSegment(type: string, initSegment: ArrayBuffer): void\n InitSegment: {\n type: string,\n data: ArrayBuffer,\n codec: string,\n container: string\n }\n */\n get onInitSegment() {\n return this._onInitSegment;\n }\n\n set onInitSegment(callback) {\n this._onInitSegment = callback;\n }\n\n /* prototype: function onMediaSegment(type: string, mediaSegment: MediaSegment): void\n MediaSegment: {\n type: string,\n data: ArrayBuffer,\n sampleCount: int32\n info: MediaSegmentInfo\n }\n */\n get onMediaSegment() {\n return this._onMediaSegment;\n }\n\n set onMediaSegment(callback) {\n this._onMediaSegment = callback;\n }\n\n insertDiscontinuity() {\n this._audioNextDts = this._videoNextDts = undefined;\n }\n\n seek(originalDts) {\n this._videoSegmentInfoList.clear();\n this._audioSegmentInfoList.clear();\n }\n\n remux(audioTrack, videoTrack) {\n if (!this._onMediaSegment) {\n throw new IllegalStateException('MP4Remuxer: onMediaSegment callback must be specificed!');\n }\n if (!this._dtsBaseInited) {\n this._calculateDtsBase(audioTrack, videoTrack);\n }\n this._remuxVideo(videoTrack);\n this._remuxAudio(audioTrack);\n }\n\n _onTrackMetadataReceived(type, metadata) {\n let metabox = null;\n\n let container = 'mp4';\n let codec = metadata.codec;\n\n if (type === 'audio') {\n this._audioMeta = metadata;\n if (metadata.codec === 'mp3' && this._mp3UseMpegAudio) {\n // 'audio/mpeg' for MP3 audio track\n container = 'mpeg';\n codec = '';\n metabox = new Uint8Array();\n } else {\n // 'audio/mp4, codecs=\"codec\"'\n metabox = MP4.generateInitSegment(metadata);\n }\n } else if (type === 'video') {\n this._videoMeta = metadata;\n metabox = MP4.generateInitSegment(metadata);\n } else {\n return;\n }\n\n // dispatch metabox (Initialization Segment)\n if (!this._onInitSegment) {\n throw new IllegalStateException('MP4Remuxer: onInitSegment callback must be specified!');\n }\n this._onInitSegment(type, {\n type: type,\n data: metabox.buffer,\n codec: codec,\n container: `${type}/${container}`,\n mediaDuration: metadata.duration // in timescale 1000 (milliseconds)\n });\n }\n\n _calculateDtsBase(audioTrack, videoTrack) {\n if (this._dtsBaseInited) {\n return;\n }\n\n if (audioTrack.samples && audioTrack.samples.length) {\n this._audioDtsBase = audioTrack.samples[0].dts;\n }\n if (videoTrack.samples && videoTrack.samples.length) {\n this._videoDtsBase = videoTrack.samples[0].dts;\n }\n\n this._dtsBase = Math.min(this._audioDtsBase, this._videoDtsBase);\n this._dtsBaseInited = true;\n }\n\n _remuxAudio(audioTrack) {\n if (this._audioMeta == null) {\n return;\n }\n\n let track = audioTrack;\n let samples = track.samples;\n let dtsCorrection = undefined;\n let firstDts = -1, lastDts = -1, lastPts = -1;\n let refSampleDuration = this._audioMeta.refSampleDuration;\n\n let mpegRawTrack = this._audioMeta.codec === 'mp3' && this._mp3UseMpegAudio;\n let firstSegmentAfterSeek = this._dtsBaseInited && this._audioNextDts === undefined;\n\n let insertPrefixSilentFrame = false;\n\n if (!samples || samples.length === 0) {\n return;\n }\n\n let offset = 0;\n let mdatbox = null;\n let mdatBytes = 0;\n\n // calculate initial mdat size\n if (mpegRawTrack) {\n // for raw mpeg buffer\n offset = 0;\n mdatBytes = track.length;\n } else {\n // for fmp4 mdat box\n offset = 8; // size + type\n mdatBytes = 8 + track.length;\n }\n\n let firstSampleOriginalDts = samples[0].dts - this._dtsBase;\n\n // calculate dtsCorrection\n if (this._audioNextDts) {\n dtsCorrection = firstSampleOriginalDts - this._audioNextDts;\n } else { // this._audioNextDts == undefined\n if (this._audioSegmentInfoList.isEmpty()) {\n dtsCorrection = 0;\n if (this._fillSilentAfterSeek && !this._videoSegmentInfoList.isEmpty()) {\n if (this._audioMeta.originalCodec !== 'mp3') {\n insertPrefixSilentFrame = true;\n }\n }\n } else {\n let lastSample = this._audioSegmentInfoList.getLastSampleBefore(firstSampleOriginalDts);\n if (lastSample != null) {\n let distance = (firstSampleOriginalDts - (lastSample.originalDts + lastSample.duration));\n if (distance <= 3) {\n distance = 0;\n }\n let expectedDts = lastSample.dts + lastSample.duration + distance;\n dtsCorrection = firstSampleOriginalDts - expectedDts;\n } else { // lastSample == null, cannot found\n dtsCorrection = 0;\n }\n }\n }\n\n if (insertPrefixSilentFrame) {\n // align audio segment beginDts to match with current video segment's beginDts\n let firstSampleDts = firstSampleOriginalDts - dtsCorrection;\n let videoSegment = this._videoSegmentInfoList.getLastSegmentBefore(firstSampleOriginalDts);\n if (videoSegment != null && videoSegment.beginDts < firstSampleDts) {\n let silentUnit = AAC.getSilentFrame(this._audioMeta.originalCodec, this._audioMeta.channelCount);\n if (silentUnit) {\n let dts = videoSegment.beginDts;\n let silentFrameDuration = firstSampleDts - videoSegment.beginDts;\n Log.v(this.TAG, `InsertPrefixSilentAudio: dts: ${dts}, duration: ${silentFrameDuration}`);\n samples.unshift({unit: silentUnit, dts: dts, pts: dts});\n mdatBytes += silentUnit.byteLength;\n } // silentUnit == null: Cannot generate, skip\n } else {\n insertPrefixSilentFrame = false;\n }\n }\n\n let mp4Samples = [];\n\n // Correct dts for each sample, and calculate sample duration. Then output to mp4Samples\n for (let i = 0; i < samples.length; i++) {\n let sample = samples[i];\n let unit = sample.unit;\n let originalDts = sample.dts - this._dtsBase;\n let dts = originalDts - dtsCorrection;\n\n if (firstDts === -1) {\n firstDts = dts;\n }\n\n let sampleDuration = 0;\n\n if (i !== samples.length - 1) {\n let nextDts = samples[i + 1].dts - this._dtsBase - dtsCorrection;\n sampleDuration = nextDts - dts;\n } else { // the last sample\n if (mp4Samples.length >= 1) { // use second last sample duration\n sampleDuration = mp4Samples[mp4Samples.length - 1].duration;\n } else { // the only one sample, use reference sample duration\n sampleDuration = Math.floor(refSampleDuration);\n }\n }\n\n let needFillSilentFrames = false;\n let silentFrames = null;\n\n // Silent frame generation, if large timestamp gap detected && config.fixAudioTimestampGap\n if (sampleDuration > refSampleDuration * 1.5 && this._audioMeta.codec !== 'mp3' && this._fillAudioTimestampGap && !Browser.safari) {\n // We need to insert silent frames to fill timestamp gap\n needFillSilentFrames = true;\n let delta = Math.abs(sampleDuration - refSampleDuration);\n let frameCount = Math.ceil(delta / refSampleDuration);\n let currentDts = dts + refSampleDuration; // Notice: in float\n\n Log.w(this.TAG, 'Large audio timestamp gap detected, may cause AV sync to drift. ' +\n 'Silent frames will be generated to avoid unsync.\\n' +\n `dts: ${dts + sampleDuration} ms, expected: ${dts + Math.round(refSampleDuration)} ms, ` +\n `delta: ${Math.round(delta)} ms, generate: ${frameCount} frames`);\n\n let silentUnit = AAC.getSilentFrame(this._audioMeta.originalCodec, this._audioMeta.channelCount);\n if (silentUnit == null) {\n Log.w(this.TAG, 'Unable to generate silent frame for ' +\n `${this._audioMeta.originalCodec} with ${this._audioMeta.channelCount} channels, repeat last frame`);\n // Repeat last frame\n silentUnit = unit;\n }\n silentFrames = [];\n\n for (let j = 0; j < frameCount; j++) {\n let intDts = Math.round(currentDts); // round to integer\n if (silentFrames.length > 0) {\n // Set previous frame sample duration\n let previousFrame = silentFrames[silentFrames.length - 1];\n previousFrame.duration = intDts - previousFrame.dts;\n }\n let frame = {\n dts: intDts,\n pts: intDts,\n cts: 0,\n unit: silentUnit,\n size: silentUnit.byteLength,\n duration: 0, // wait for next sample\n originalDts: originalDts,\n flags: {\n isLeading: 0,\n dependsOn: 1,\n isDependedOn: 0,\n hasRedundancy: 0\n }\n };\n silentFrames.push(frame);\n mdatBytes += unit.byteLength;\n currentDts += refSampleDuration;\n }\n\n // last frame: align end time to next frame dts\n let lastFrame = silentFrames[silentFrames.length - 1];\n lastFrame.duration = dts + sampleDuration - lastFrame.dts;\n\n // silentFrames.forEach((frame) => {\n // Log.w(this.TAG, `SilentAudio: dts: ${frame.dts}, duration: ${frame.duration}`);\n // });\n\n // Set correct sample duration for current frame\n sampleDuration = Math.round(refSampleDuration);\n }\n\n mp4Samples.push({\n dts: dts,\n pts: dts,\n cts: 0,\n unit: sample.unit,\n size: sample.unit.byteLength,\n duration: sampleDuration,\n originalDts: originalDts,\n flags: {\n isLeading: 0,\n dependsOn: 1,\n isDependedOn: 0,\n hasRedundancy: 0\n }\n });\n\n if (needFillSilentFrames) {\n // Silent frames should be inserted after wrong-duration frame\n mp4Samples.push.apply(mp4Samples, silentFrames);\n }\n }\n\n // allocate mdatbox\n if (mpegRawTrack) {\n // allocate for raw mpeg buffer\n mdatbox = new Uint8Array(mdatBytes);\n } else {\n // allocate for fmp4 mdat box\n mdatbox = new Uint8Array(mdatBytes);\n // size field\n mdatbox[0] = (mdatBytes >>> 24) & 0xFF;\n mdatbox[1] = (mdatBytes >>> 16) & 0xFF;\n mdatbox[2] = (mdatBytes >>> 8) & 0xFF;\n mdatbox[3] = (mdatBytes) & 0xFF;\n // type field (fourCC)\n mdatbox.set(MP4.types.mdat, 4);\n }\n\n // Write samples into mdatbox\n for (let i = 0; i < mp4Samples.length; i++) {\n let unit = mp4Samples[i].unit;\n mdatbox.set(unit, offset);\n offset += unit.byteLength;\n }\n\n let latest = mp4Samples[mp4Samples.length - 1];\n lastDts = latest.dts + latest.duration;\n this._audioNextDts = lastDts;\n\n // fill media segment info & add to info list\n let info = new MediaSegmentInfo();\n info.beginDts = firstDts;\n info.endDts = lastDts;\n info.beginPts = firstDts;\n info.endPts = lastDts;\n info.originalBeginDts = mp4Samples[0].originalDts;\n info.originalEndDts = latest.originalDts + latest.duration;\n info.firstSample = new SampleInfo(mp4Samples[0].dts,\n mp4Samples[0].pts,\n mp4Samples[0].duration,\n mp4Samples[0].originalDts,\n false);\n info.lastSample = new SampleInfo(latest.dts,\n latest.pts,\n latest.duration,\n latest.originalDts,\n false);\n if (!this._isLive) {\n this._audioSegmentInfoList.append(info);\n }\n\n track.samples = mp4Samples;\n track.sequenceNumber++;\n\n let moofbox = null;\n\n if (mpegRawTrack) {\n // Generate empty buffer, because useless for raw mpeg\n moofbox = new Uint8Array();\n } else {\n // Generate moof for fmp4 segment\n moofbox = MP4.moof(track, firstDts);\n }\n\n track.samples = [];\n track.length = 0;\n\n let segment = {\n type: 'audio',\n data: this._mergeBoxes(moofbox, mdatbox).buffer,\n sampleCount: mp4Samples.length,\n info: info\n };\n\n if (mpegRawTrack && firstSegmentAfterSeek) {\n // For MPEG audio stream in MSE, if seeking occurred, before appending new buffer\n // We need explicitly set timestampOffset to the desired point in timeline for mpeg SourceBuffer.\n segment.timestampOffset = firstDts;\n }\n\n this._onMediaSegment('audio', segment);\n }\n\n _remuxVideo(videoTrack) {\n if (this._videoMeta == null) {\n return;\n }\n\n let track = videoTrack;\n let samples = track.samples;\n let dtsCorrection = undefined;\n let firstDts = -1, lastDts = -1;\n let firstPts = -1, lastPts = -1;\n\n if (!samples || samples.length === 0) {\n return;\n }\n\n let offset = 8;\n let mdatBytes = 8 + videoTrack.length;\n let mdatbox = new Uint8Array(mdatBytes);\n mdatbox[0] = (mdatBytes >>> 24) & 0xFF;\n mdatbox[1] = (mdatBytes >>> 16) & 0xFF;\n mdatbox[2] = (mdatBytes >>> 8) & 0xFF;\n mdatbox[3] = (mdatBytes) & 0xFF;\n mdatbox.set(MP4.types.mdat, 4);\n\n let firstSampleOriginalDts = samples[0].dts - this._dtsBase;\n\n // calculate dtsCorrection\n if (this._videoNextDts) {\n dtsCorrection = firstSampleOriginalDts - this._videoNextDts;\n } else { // this._videoNextDts == undefined\n if (this._videoSegmentInfoList.isEmpty()) {\n dtsCorrection = 0;\n } else {\n let lastSample = this._videoSegmentInfoList.getLastSampleBefore(firstSampleOriginalDts);\n if (lastSample != null) {\n let distance = (firstSampleOriginalDts - (lastSample.originalDts + lastSample.duration));\n if (distance <= 3) {\n distance = 0;\n }\n let expectedDts = lastSample.dts + lastSample.duration + distance;\n dtsCorrection = firstSampleOriginalDts - expectedDts;\n } else { // lastSample == null, cannot found\n dtsCorrection = 0;\n }\n }\n }\n\n let info = new MediaSegmentInfo();\n let mp4Samples = [];\n\n // Correct dts for each sample, and calculate sample duration. Then output to mp4Samples\n for (let i = 0; i < samples.length; i++) {\n let sample = samples[i];\n let originalDts = sample.dts - this._dtsBase;\n let isKeyframe = sample.isKeyframe;\n let dts = originalDts - dtsCorrection;\n let cts = sample.cts;\n let pts = dts + cts;\n\n if (firstDts === -1) {\n firstDts = dts;\n firstPts = pts;\n }\n\n let sampleDuration = 0;\n\n if (i !== samples.length - 1) {\n let nextDts = samples[i + 1].dts - this._dtsBase - dtsCorrection;\n sampleDuration = nextDts - dts;\n } else { // the last sample\n if (mp4Samples.length >= 1) { // use second last sample duration\n sampleDuration = mp4Samples[mp4Samples.length - 1].duration;\n } else { // the only one sample, use reference sample duration\n sampleDuration = Math.floor(this._videoMeta.refSampleDuration);\n }\n }\n\n if (isKeyframe) {\n let syncPoint = new SampleInfo(dts, pts, sampleDuration, sample.dts, true);\n syncPoint.fileposition = sample.fileposition;\n info.appendSyncPoint(syncPoint);\n }\n\n mp4Samples.push({\n dts: dts,\n pts: pts,\n cts: cts,\n units: sample.units,\n size: sample.length,\n isKeyframe: isKeyframe,\n duration: sampleDuration,\n originalDts: originalDts,\n flags: {\n isLeading: 0,\n dependsOn: isKeyframe ? 2 : 1,\n isDependedOn: isKeyframe ? 1 : 0,\n hasRedundancy: 0,\n isNonSync: isKeyframe ? 0 : 1\n }\n });\n }\n\n // Write samples into mdatbox\n for (let i = 0; i < mp4Samples.length; i++) {\n let units = mp4Samples[i].units;\n while (units.length) {\n let unit = units.shift();\n let data = unit.data;\n mdatbox.set(data, offset);\n offset += data.byteLength;\n }\n }\n\n let latest = mp4Samples[mp4Samples.length - 1];\n lastDts = latest.dts + latest.duration;\n lastPts = latest.pts + latest.duration;\n this._videoNextDts = lastDts;\n\n // fill media segment info & add to info list\n info.beginDts = firstDts;\n info.endDts = lastDts;\n info.beginPts = firstPts;\n info.endPts = lastPts;\n info.originalBeginDts = mp4Samples[0].originalDts;\n info.originalEndDts = latest.originalDts + latest.duration;\n info.firstSample = new SampleInfo(mp4Samples[0].dts,\n mp4Samples[0].pts,\n mp4Samples[0].duration,\n mp4Samples[0].originalDts,\n mp4Samples[0].isKeyframe);\n info.lastSample = new SampleInfo(latest.dts,\n latest.pts,\n latest.duration,\n latest.originalDts,\n latest.isKeyframe);\n if (!this._isLive) {\n this._videoSegmentInfoList.append(info);\n }\n\n track.samples = mp4Samples;\n track.sequenceNumber++;\n\n // workaround for chrome < 50: force first sample as a random access point\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=229412\n if (this._forceFirstIDR) {\n let flags = mp4Samples[0].flags;\n flags.dependsOn = 2;\n flags.isNonSync = 0;\n }\n\n let moofbox = MP4.moof(track, firstDts);\n track.samples = [];\n track.length = 0;\n\n this._onMediaSegment('video', {\n type: 'video',\n data: this._mergeBoxes(moofbox, mdatbox).buffer,\n sampleCount: mp4Samples.length,\n info: info\n });\n }\n\n _mergeBoxes(moof, mdat) {\n let result = new Uint8Array(moof.byteLength + mdat.byteLength);\n result.set(moof, 0);\n result.set(mdat, moof.byteLength);\n return result;\n }\n\n}\n\nexport default MP4Remuxer;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nlet Browser = {};\n\nfunction detect() {\n // modified from jquery-browser-plugin\n\n let ua = self.navigator.userAgent.toLowerCase();\n\n let match = /(edge)\\/([\\w.]+)/.exec(ua) ||\n /(opr)[\\/]([\\w.]+)/.exec(ua) ||\n /(chrome)[ \\/]([\\w.]+)/.exec(ua) ||\n /(iemobile)[\\/]([\\w.]+)/.exec(ua) ||\n /(version)(applewebkit)[ \\/]([\\w.]+).*(safari)[ \\/]([\\w.]+)/.exec(ua) ||\n /(webkit)[ \\/]([\\w.]+).*(version)[ \\/]([\\w.]+).*(safari)[ \\/]([\\w.]+)/.exec(ua) ||\n /(webkit)[ \\/]([\\w.]+)/.exec(ua) ||\n /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec(ua) ||\n /(msie) ([\\w.]+)/.exec(ua) ||\n ua.indexOf('trident') >= 0 && /(rv)(?::| )([\\w.]+)/.exec(ua) ||\n ua.indexOf('compatible') < 0 && /(firefox)[ \\/]([\\w.]+)/.exec(ua) ||\n [];\n\n let platform_match = /(ipad)/.exec(ua) ||\n /(ipod)/.exec(ua) ||\n /(windows phone)/.exec(ua) ||\n /(iphone)/.exec(ua) ||\n /(kindle)/.exec(ua) ||\n /(android)/.exec(ua) ||\n /(windows)/.exec(ua) ||\n /(mac)/.exec(ua) ||\n /(linux)/.exec(ua) ||\n /(cros)/.exec(ua) ||\n [];\n\n let matched = {\n browser: match[5] || match[3] || match[1] || '',\n version: match[2] || match[4] || '0',\n majorVersion: match[4] || match[2] || '0',\n platform: platform_match[0] || ''\n };\n\n let browser = {};\n if (matched.browser) {\n browser[matched.browser] = true;\n\n let versionArray = matched.majorVersion.split('.');\n browser.version = {\n major: parseInt(matched.majorVersion, 10),\n string: matched.version\n };\n if (versionArray.length > 1) {\n browser.version.minor = parseInt(versionArray[1], 10);\n }\n if (versionArray.length > 2) {\n browser.version.build = parseInt(versionArray[2], 10);\n }\n }\n\n if (matched.platform) {\n browser[matched.platform] = true;\n }\n\n if (browser.chrome || browser.opr || browser.safari) {\n browser.webkit = true;\n }\n\n // MSIE. IE11 has 'rv' identifer\n if (browser.rv || browser.iemobile) {\n if (browser.rv) {\n delete browser.rv;\n }\n let msie = 'msie';\n matched.browser = msie;\n browser[msie] = true;\n }\n\n // Microsoft Edge\n if (browser.edge) {\n delete browser.edge;\n let msedge = 'msedge';\n matched.browser = msedge;\n browser[msedge] = true;\n }\n\n // Opera 15+\n if (browser.opr) {\n let opera = 'opera';\n matched.browser = opera;\n browser[opera] = true;\n }\n\n // Stock android browsers are marked as Safari\n if (browser.safari && browser.android) {\n let android = 'android';\n matched.browser = android;\n browser[android] = true;\n }\n\n browser.name = matched.browser;\n browser.platform = matched.platform;\n\n for (let key in Browser) {\n if (Browser.hasOwnProperty(key)) {\n delete Browser[key];\n }\n }\n Object.assign(Browser, browser);\n}\n\ndetect();\n\nexport default Browser;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class RuntimeException {\n\n constructor(message) {\n this._message = message;\n }\n\n get name() {\n return 'RuntimeException';\n }\n\n get message() {\n return this._message;\n }\n\n toString() {\n return this.name + ': ' + this.message;\n }\n\n}\n\nexport class IllegalStateException extends RuntimeException {\n\n constructor(message) {\n super(message);\n }\n\n get name() {\n return 'IllegalStateException';\n }\n\n}\n\nexport class InvalidArgumentException extends RuntimeException {\n\n constructor(message) {\n super(message);\n }\n\n get name() {\n return 'InvalidArgumentException';\n }\n\n}\n\nexport class NotImplementedException extends RuntimeException {\n\n constructor(message) {\n super(message);\n }\n\n get name() {\n return 'NotImplementedException';\n }\n\n}\n","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\n\nclass Log {\n\n static e(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'error', str);\n }\n\n if (!Log.ENABLE_ERROR) {\n return;\n }\n\n if (console.error) {\n console.error(str);\n } else if (console.warn) {\n console.warn(str);\n } else {\n console.log(str);\n }\n }\n\n static i(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'info', str);\n }\n\n if (!Log.ENABLE_INFO) {\n return;\n }\n\n if (console.info) {\n console.info(str);\n } else {\n console.log(str);\n }\n }\n\n static w(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'warn', str);\n }\n\n if (!Log.ENABLE_WARN) {\n return;\n }\n\n if (console.warn) {\n console.warn(str);\n } else {\n console.log(str);\n }\n }\n\n static d(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'debug', str);\n }\n\n if (!Log.ENABLE_DEBUG) {\n return;\n }\n\n if (console.debug) {\n console.debug(str);\n } else {\n console.log(str);\n }\n }\n\n static v(tag, msg) {\n if (!tag || Log.FORCE_GLOBAL_TAG)\n tag = Log.GLOBAL_TAG;\n\n let str = `[${tag}] > ${msg}`;\n\n if (Log.ENABLE_CALLBACK) {\n Log.emitter.emit('log', 'verbose', str);\n }\n\n if (!Log.ENABLE_VERBOSE) {\n return;\n }\n\n console.log(str);\n }\n\n}\n\nLog.GLOBAL_TAG = 'flv.js';\nLog.FORCE_GLOBAL_TAG = false;\nLog.ENABLE_ERROR = true;\nLog.ENABLE_INFO = true;\nLog.ENABLE_WARN = true;\nLog.ENABLE_DEBUG = true;\nLog.ENABLE_VERBOSE = true;\n\nLog.ENABLE_CALLBACK = false;\n\nLog.emitter = new EventEmitter();\n\nexport default Log;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport EventEmitter from 'events';\nimport Log from './logger.js';\n\nclass LoggingControl {\n\n static get forceGlobalTag() {\n return Log.FORCE_GLOBAL_TAG;\n }\n\n static set forceGlobalTag(enable) {\n Log.FORCE_GLOBAL_TAG = enable;\n LoggingControl._notifyChange();\n }\n\n static get globalTag() {\n return Log.GLOBAL_TAG;\n }\n\n static set globalTag(tag) {\n Log.GLOBAL_TAG = tag;\n LoggingControl._notifyChange();\n }\n\n static get enableAll() {\n return Log.ENABLE_VERBOSE\n && Log.ENABLE_DEBUG\n && Log.ENABLE_INFO\n && Log.ENABLE_WARN\n && Log.ENABLE_ERROR;\n }\n\n static set enableAll(enable) {\n Log.ENABLE_VERBOSE = enable;\n Log.ENABLE_DEBUG = enable;\n Log.ENABLE_INFO = enable;\n Log.ENABLE_WARN = enable;\n Log.ENABLE_ERROR = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableDebug() {\n return Log.ENABLE_DEBUG;\n }\n\n static set enableDebug(enable) {\n Log.ENABLE_DEBUG = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableVerbose() {\n return Log.ENABLE_VERBOSE;\n }\n\n static set enableVerbose(enable) {\n Log.ENABLE_VERBOSE = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableInfo() {\n return Log.ENABLE_INFO;\n }\n\n static set enableInfo(enable) {\n Log.ENABLE_INFO = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableWarn() {\n return Log.ENABLE_WARN;\n }\n\n static set enableWarn(enable) {\n Log.ENABLE_WARN = enable;\n LoggingControl._notifyChange();\n }\n\n static get enableError() {\n return Log.ENABLE_ERROR;\n }\n\n static set enableError(enable) {\n Log.ENABLE_ERROR = enable;\n LoggingControl._notifyChange();\n }\n\n static getConfig() {\n return {\n globalTag: Log.GLOBAL_TAG,\n forceGlobalTag: Log.FORCE_GLOBAL_TAG,\n enableVerbose: Log.ENABLE_VERBOSE,\n enableDebug: Log.ENABLE_DEBUG,\n enableInfo: Log.ENABLE_INFO,\n enableWarn: Log.ENABLE_WARN,\n enableError: Log.ENABLE_ERROR,\n enableCallback: Log.ENABLE_CALLBACK\n };\n }\n\n static applyConfig(config) {\n Log.GLOBAL_TAG = config.globalTag;\n Log.FORCE_GLOBAL_TAG = config.forceGlobalTag;\n Log.ENABLE_VERBOSE = config.enableVerbose;\n Log.ENABLE_DEBUG = config.enableDebug;\n Log.ENABLE_INFO = config.enableInfo;\n Log.ENABLE_WARN = config.enableWarn;\n Log.ENABLE_ERROR = config.enableError;\n Log.ENABLE_CALLBACK = config.enableCallback;\n }\n\n static _notifyChange() {\n let emitter = LoggingControl.emitter;\n\n if (emitter.listenerCount('change') > 0) {\n let config = LoggingControl.getConfig();\n emitter.emit('change', config);\n }\n }\n\n static registerListener(listener) {\n LoggingControl.emitter.addListener('change', listener);\n }\n\n static removeListener(listener) {\n LoggingControl.emitter.removeListener('change', listener);\n }\n\n static addLogListener(listener) {\n Log.emitter.addListener('log', listener);\n if (Log.emitter.listenerCount('log') > 0) {\n Log.ENABLE_CALLBACK = true;\n LoggingControl._notifyChange();\n }\n }\n\n static removeLogListener(listener) {\n Log.emitter.removeListener('log', listener);\n if (Log.emitter.listenerCount('log') === 0) {\n Log.ENABLE_CALLBACK = false;\n LoggingControl._notifyChange();\n }\n }\n\n}\n\nLoggingControl.emitter = new EventEmitter();\n\nexport default LoggingControl;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass Polyfill {\n\n static install() {\n // ES6 Object.setPrototypeOf\n Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {\n obj.__proto__ = proto;\n return obj;\n };\n\n // ES6 Object.assign\n Object.assign = Object.assign || function (target) {\n if (target === undefined || target === null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n let output = Object(target);\n for (let i = 1; i < arguments.length; i++) {\n let source = arguments[i];\n if (source !== undefined && source !== null) {\n for (let key in source) {\n if (source.hasOwnProperty(key)) {\n output[key] = source[key];\n }\n }\n }\n }\n return output;\n };\n\n // ES6 Promise (missing support in IE11)\n if (typeof self.Promise !== 'function') {\n require('es6-promise').polyfill();\n }\n }\n\n}\n\nPolyfill.install();\n\nexport default Polyfill;","/*\n * Copyright (C) 2016 Bilibili. All Rights Reserved.\n *\n * This file is derived from C++ project libWinTF8 (https://github.com/m13253/libWinTF8)\n * @author zheng qian \n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nfunction checkContinuation(uint8array, start, checkLength) {\n let array = uint8array;\n if (start + checkLength < array.length) {\n while (checkLength--) {\n if ((array[++start] & 0xC0) !== 0x80)\n return false;\n }\n return true;\n } else {\n return false;\n }\n}\n\nfunction decodeUTF8(uint8array) {\n let out = [];\n let input = uint8array;\n let i = 0;\n let length = uint8array.length;\n\n while (i < length) {\n if (input[i] < 0x80) {\n out.push(String.fromCharCode(input[i]));\n ++i;\n continue;\n } else if (input[i] < 0xC0) {\n // fallthrough\n } else if (input[i] < 0xE0) {\n if (checkContinuation(input, i, 1)) {\n let ucs4 = (input[i] & 0x1F) << 6 | (input[i + 1] & 0x3F);\n if (ucs4 >= 0x80) {\n out.push(String.fromCharCode(ucs4 & 0xFFFF));\n i += 2;\n continue;\n }\n }\n } else if (input[i] < 0xF0) {\n if (checkContinuation(input, i, 2)) {\n let ucs4 = (input[i] & 0xF) << 12 | (input[i + 1] & 0x3F) << 6 | input[i + 2] & 0x3F;\n if (ucs4 >= 0x800 && (ucs4 & 0xF800) !== 0xD800) {\n out.push(String.fromCharCode(ucs4 & 0xFFFF));\n i += 3;\n continue;\n }\n }\n } else if (input[i] < 0xF8) {\n if (checkContinuation(input, i, 3)) {\n let ucs4 = (input[i] & 0x7) << 18 | (input[i + 1] & 0x3F) << 12\n | (input[i + 2] & 0x3F) << 6 | (input[i + 3] & 0x3F);\n if (ucs4 > 0x10000 && ucs4 < 0x110000) {\n ucs4 -= 0x10000;\n out.push(String.fromCharCode((ucs4 >>> 10) | 0xD800));\n out.push(String.fromCharCode((ucs4 & 0x3FF) | 0xDC00));\n i += 4;\n continue;\n }\n }\n }\n out.push(String.fromCharCode(0xFFFD));\n ++i;\n }\n\n return out.join('');\n}\n\nexport default decodeUTF8;"]} \ No newline at end of file diff --git a/tools/MP4 Stream/index.html b/tools/MP4 Stream/index.html new file mode 100644 index 0000000..bf4a4ec --- /dev/null +++ b/tools/MP4 Stream/index.html @@ -0,0 +1,29 @@ + + + + + + + FLV to Web Test by Shinobi Systems + + + + + + + \ No newline at end of file diff --git a/tools/addVideos.js.disabled b/tools/addVideos.js.disabled new file mode 100644 index 0000000..e791f3f --- /dev/null +++ b/tools/addVideos.js.disabled @@ -0,0 +1,48 @@ +//add videos to SQL tables from filesystem +var fs = require('fs'); +var moment = require('moment'); +var mysql = require('mysql'); +var config = require('../conf.json'); +s={} +s.disc=function(){ + sql = mysql.createConnection(config.db); + sql.connect(function(err){if(err){console.log('Error Connecting : DB',err);setTimeout(s.disc, 2000);}}); + sql.on('error',function(err) {console.log('DB Lost.. Retrying..');console.log(err);s.disc();return;}); +} +s.disc(); +if(!config.videosDir){config.videosDir=__dirname+'/../videos/'} +s.dir={videos:config.videosDir}; +s.nameToTime=function(x){x=x.split('.')[0].split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;} +s.moment=function(e,x){ + if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'}; + return moment(e).format(x); +} +fs.readdir(s.dir.videos,function(err,groups){ + groups.forEach(function(group){ + fs.readdir(s.dir.videos+group,function(err,cameras){ + cameras.forEach(function(camera){ + fs.readdir(s.dir.videos+group+'/'+camera,function(err,videos){ + sql.query('SELECT * FROM Videos WHERE ke=? AND mid=?',[group,camera],function(err,r){ + videos.forEach(function(filename){ + fs.stat(s.dir.videos+group+'/'+camera+'/'+filename,function(err,file){ + file.startTime=s.nameToTime(filename) + file.endTime=s.moment(file.mtime,'YYYY-MM-DD HH:mm:ss') + var save=[camera,group,filename.split('.')[1],file.size,file.startTime,file.endTime,1] + var found=null + r.forEach(function(v){ + if(s.moment(v.time,'YYYY-MM-DD HH:mm:ss')===file.startTime){ + found=v + } + }) + if(!found){ + console.log('!found',save) + sql.query('INSERT INTO Videos (mid,ke,ext,size,time,end,status) VALUES (?,?,?,?,?,?,?)',save) + } + }) + }) + }) + }) + }) + }) + }) +}) \ No newline at end of file diff --git a/tools/checkNPM.js b/tools/checkNPM.js new file mode 100644 index 0000000..ef2bdf5 --- /dev/null +++ b/tools/checkNPM.js @@ -0,0 +1,10 @@ +var fs=require('fs'); +function npmls(cb) { + require('child_process').exec('npm ls --json', function(err, stdout, stderr) { + if (err) return cb(err) + cb(null, JSON.stringify(JSON.parse(stdout),null,3)); + }); +} +npmls(function(yolo,stdout){ +fs.writeFileSync(__dirname+'/npmls.json',stdout) +}); diff --git a/tools/coco/testCoco.js b/tools/coco/testCoco.js new file mode 100644 index 0000000..b675ba8 --- /dev/null +++ b/tools/coco/testCoco.js @@ -0,0 +1,103 @@ +var cv = require('opencv4nodejs') +const fs = require('fs'); +const path = require('path'); +const classNames = require('./dnnCocoClassNames'); +const { extractResults } = require('./dnn/ssdUtils'); + +if (!cv.xmodules.dnn) { + throw new Error('exiting: opencv4nodejs compiled without dnn module'); +} + +// replace with path where you unzipped inception model +const ssdcocoModelPath = '../data/dnn/coco-SSD_300x300'; + +const prototxt = path.resolve(ssdcocoModelPath, 'deploy.prototxt'); +const modelFile = path.resolve(ssdcocoModelPath, 'VGG_coco_SSD_300x300_iter_400000.caffemodel'); + +if (!fs.existsSync(prototxt) || !fs.existsSync(modelFile)) { + console.log('could not find ssdcoco model'); + console.log('download the model from: https://drive.google.com/file/d/0BzKzrI_SkD1_dUY1Ml9GRTFpUWc/view'); + throw new Error('exiting: could not find ssdcoco model'); +} + +// initialize ssdcoco model from prototxt and modelFile +const net = cv.readNetFromCaffe(prototxt, modelFile); + +function classifyImg(img) { + // ssdcoco model works with 300 x 300 images + const imgResized = img.resize(300, 300); + + // network accepts blobs as input + const inputBlob = cv.blobFromImage(imgResized); + net.setInput(inputBlob); + + // forward pass input through entire network, will return + // classification result as 1x1xNxM Mat + let outputBlob = net.forward(); + // extract NxM Mat + outputBlob = outputBlob.flattenFloat(outputBlob.sizes[2], outputBlob.sizes[3]); + + return extractResults(outputBlob, img) + .map(r => Object.assign({}, r, { className: classNames[r.classLabel] })); +} + +const makeDrawClassDetections = predictions => (drawImg, className, getColor, thickness = 2) => { + predictions + .filter(p => classNames[p.classLabel] === className) + .forEach(p => drawRect(drawImg, p.rect, getColor(), { thickness })); + return drawImg; +}; + +const runDetectDishesExample = () => { + const img = cv.imread('../data/dishes.jpg'); + const minConfidence = 0.2; + + const predictions = classifyImg(img).filter(res => res.confidence > minConfidence); + + const drawClassDetections = makeDrawClassDetections(predictions); + + const classColors = { + fork: new cv.Vec(0, 255, 0), + bowl: new cv.Vec(255, 0, 0), + 'wine glass': new cv.Vec(0, 0, 255), + cup: new cv.Vec(0, 255, 255) + }; + + const legendLeftTop = new cv.Point(580, 20); + const alpha = 0.4; + cv.drawTextBox( + img, + legendLeftTop, + Object.keys(classColors).map(className => ({ + text: className, + fontSize: 0.8, + color: classColors[className] + })), + alpha + ); + + Object.keys(classColors).forEach((className) => { + const color = classColors[className]; + // draw detections + drawClassDetections(img, className, () => color); + }); + + cv.imshowWait('img', img); +}; + +const runDetectPeopleExample = () => { + const img = cv.imread('../data/cars.jpeg'); + const minConfidence = 0.4; + + const predictions = classifyImg(img).filter(res => res.confidence > minConfidence); + + const drawClassDetections = makeDrawClassDetections(predictions); + + const getRandomColor = () => new cv.Vec(Math.random() * 255, Math.random() * 255, 255); + + drawClassDetections(img, 'car', getRandomColor); + cv.imshowWait('img', img); +}; + +runDetectDishesExample(); +runDetectPeopleExample(); \ No newline at end of file diff --git a/tools/cron.js b/tools/cron.js new file mode 100644 index 0000000..d84c34d --- /dev/null +++ b/tools/cron.js @@ -0,0 +1,405 @@ + +var fs = require('fs'); +var path = require('path'); +var mysql = require('mysql'); +var moment = require('moment'); +var exec = require('child_process').exec; +var spawn = require('child_process').spawn; +var config=require(__dirname+'/../conf.json'); +var sql=mysql.createConnection(config.db); + +//set option defaults +s={}; +if(config.cron===undefined)config.cron={}; +if(config.cron.enabled===undefined)config.cron.enabled=true; +if(config.cron.deleteOld===undefined)config.cron.deleteOld=true; +if(config.cron.deleteOrphans===undefined)config.cron.deleteOrphans=false; +if(config.cron.deleteNoVideo===undefined)config.cron.deleteNoVideo=true; +if(config.cron.deleteNoVideoRecursion===undefined)config.cron.deleteNoVideoRecursion=false; +if(config.cron.deleteOverMax===undefined)config.cron.deleteOverMax=true; +if(config.cron.deleteLogs===undefined)config.cron.deleteLogs=true; +if(config.cron.deleteEvents===undefined)config.cron.deleteEvents=true; +if(config.cron.deleteFileBins===undefined)config.cron.deleteFileBins=true; +if(config.cron.interval===undefined)config.cron.interval=1; + +if(!config.ip||config.ip===''||config.ip.indexOf('0.0.0.0')>-1)config.ip='localhost'; +if(!config.videosDir)config.videosDir=__dirname+'/videos/'; +if(!config.binDir){config.binDir=__dirname+'/fileBin/'} +if(!config.addStorage){config.addStorage=[]} +//containers +cronOverlapLock={}; +cronAlreadyDeletedRowsWithNoVideosOnStart={}; +//functions +module.exports.checkCorrectPathEnding=function(x){ + var length=x.length + if(x.charAt(length-1)!=='/'){ + x=x+'/' + } + return x.replace('__DIR__',__dirname) +} +module.exports.dir={ + videos:module.exports.checkCorrectPathEnding(config.videosDir), + fileBin:module.exports.checkCorrectPathEnding(config.binDir), + addStorage:config.addStorage, +}; +module.exports.moment=function(e,x){ + if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'}; + return moment(e).format(x); +} +module.exports.nameToTime=function(x){x=x.replace('.webm','').replace('.mp4','').split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;} +io = require('socket.io-client')('ws://'+config.ip+':'+config.port);//connect to master +module.exports.cx=function(x){x.cronKey=config.cron.key;return io.emit('cron',x)} +//emulate master socket emitter +module.exports.tx=function(x,y){module.exports.cx({f:'module.exports.tx',data:x,to:y})} +module.exports.video=function(x,y){module.exports.cx({f:'module.exports.video',data:x,file:y})} +//Cron Job +module.exports.cx({f:'init',time:moment()}) +module.exports.getVideoDirectory=function(e){ + if(e.mid&&!e.id){e.id=e.mid}; + if(e.details&&(e.details instanceof Object)===false){ + try{e.details=JSON.parse(e.details)}catch(err){} + } + if(e.details.dir&&e.details.dir!==''){ + return module.exports.checkCorrectPathEnding(e.details.dir)+e.ke+'/'+e.id+'/' + }else{ + return module.exports.dir.videos+e.ke+'/'+e.id+'/'; + } +} +module.exports.getFileBinDirectory=function(e){ + if(e.mid&&!e.id){e.id=e.mid}; + return module.exports.dir.fileBin+e.ke+'/'+e.id+'/'; +} +//filters set by the user in their dashboard +//deleting old videos is part of the filter - config.cron.deleteOld +module.exports.cronCheckFilterRules=function(v,callback){ + //filters + if(!v.d.filters||v.d.filters==''){ + v.d.filters={}; + } + //delete old videos with filter + if(config.cron.deleteOld===true){ + v.d.filters.deleteOldByCron={ + "id":"deleteOldByCron", + "name":"deleteOldByCron", + "sort_by":"time", + "sort_by_direction":"ASC", + "limit":"", + "enabled":"1", + "archive":"0", + "email":"0", + "delete":"1", + "execute":"", + "where":[{ + "p1":"end", + "p2":"<", + "p3":"NOW() - INTERVAL "+(v.maxVideoDays[v.mid]*24)+" HOUR", + "p3_type":"function", + }] + }; + } + var keys = Object.keys(v.d.filters) + if(keys.length>0){ + keys.forEach(function(m,current){ + var b=v.d.filters[m]; + if(b.enabled==="1"){ + b.ar=[v.ke]; + b.sql=[]; + b.where.forEach(function(j,k){ + if(j.p1==='ke'){j.p3=v.ke} + switch(j.p3_type){ + case'function': + b.sql.push(j.p1+' '+j.p2+' '+j.p3) + break; + default: + b.sql.push(j.p1+' '+j.p2+' ?') + b.ar.push(j.p3) + break; + } + }) + b.sql='WHERE ke=? AND status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND ('+b.sql.join(' AND ')+')'; + if(b.sort_by&&b.sort_by!==''){ + b.sql+=' ORDER BY `'+b.sort_by+'` '+b.sort_by_direction + } + if(b.limit&&b.limit!==''){ + b.sql+=' LIMIT '+b.limit + } + sql.query('SELECT * FROM Videos '+b.sql,b.ar,function(err,r){ + if(r&&r[0]){ + b.cx={ + f:'filters', + name:b.name, + videos:r, + time:moment(), + ke:v.ke, + id:b.id + }; + if(b.archive==="1"){ + module.exports.cx({f:'filters',ff:'archive',videos:r,time:moment(),ke:v.ke,id:b.id}); + }else{ + if(b.delete==="1"){ + module.exports.cx({f:'filters',ff:'delete',videos:r,time:moment(),ke:v.ke,id:b.id}); + } + } + if(b.email==="1"){ + b.cx.ff='email'; + b.cx.delete=b.delete; + b.cx.mail=v.mail; + b.cx.execute=b.execute; + b.cx.query=b.sql; + module.exports.cx(b.cx); + } + if(b.execute&&b.execute!==""){ + module.exports.cx({f:'filters',ff:'execute',execute:b.execute,time:moment()}); + } + } + }) + + } + if(current===keys.length-1){ + //last filter + callback() + } + }) + }else{ + //no filters + callback() + } +} +//database rows with no videos in the filesystem +module.exports.cronDeleteRowsWithNoVideo=function(v,callback){ + if( + config.cron.deleteNoVideo===true&&( + config.cron.deleteNoVideoRecursion===true|| + (config.cron.deleteNoVideoRecursion===false&&!cronAlreadyDeletedRowsWithNoVideosOnStart[v.ke]) + ) + ){ + cronAlreadyDeletedRowsWithNoVideosOnStart[v.ke]=true; + es={}; + sql.query('SELECT * FROM Videos WHERE ke = ? AND status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND time < (NOW() - INTERVAL 10 MINUTE)',[v.ke],function(err,evs){ + if(evs&&evs[0]){ + es.del=[];es.ar=[v.ke]; + evs.forEach(function(ev){ + ev.dir=module.exports.getVideoDirectory(ev)+module.exports.moment(ev.time)+'.'+ev.ext; + if(fs.existsSync(ev.dir)!==true){ + module.exports.video('delete',ev) + es.del.push('(mid=? AND time=?)'); + es.ar.push(ev.mid),es.ar.push(ev.time); + module.exports.tx({f:'video_delete',filename:module.exports.moment(ev.time)+'.'+ev.ext,mid:ev.mid,ke:ev.ke,time:ev.time,end:module.exports.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+ev.ke); + } + }); + if(es.del.length>0){ + module.exports.cx({f:'deleteNoVideo',msg:es.del.length+' SQL rows with no file deleted',ke:v.ke,time:moment()}) + } + } + setTimeout(function(){ + callback() + },3000) + }) + }else{ + callback() + } +} +//info about what the application is doing +module.exports.cronDeleteOldLogs=function(v,callback){ + if(!v.d.log_days||v.d.log_days==''){v.d.log_days=10}else{v.d.log_days=parseFloat(v.d.log_days)}; + if(config.cron.deleteLogs===true&&v.d.log_days!==0){ + sql.query("DELETE FROM Logs WHERE ke=? AND `time` < DATE_SUB(NOW(), INTERVAL ? DAY)",[v.ke,v.d.log_days],function(err,rrr){ + callback() + if(err)return console.error(err); + if(rrr.affectedRows.length>0){ + module.exports.cx({f:'deleteLogs',msg:rrr.affectedRows+' SQL rows older than '+v.d.log_days+' days deleted',ke:v.ke,time:moment()}) + } + }) + }else{ + callback() + } +} +//events - motion, object, etc. detections +module.exports.cronDeleteOldEvents=function(v,callback){ + if(!v.d.event_days||v.d.event_days==''){v.d.event_days=10}else{v.d.event_days=parseFloat(v.d.event_days)}; + if(config.cron.deleteEvents===true&&v.d.event_days!==0){ + sql.query("DELETE FROM Events WHERE ke=? AND `time` < DATE_SUB(NOW(), INTERVAL ? DAY)",[v.ke,v.d.event_days],function(err,rrr){ + callback() + if(err)return console.error(err); + if(rrr.affectedRows.length>0){ + module.exports.cx({f:'deleteEvents',msg:rrr.affectedRows+' SQL rows older than '+v.d.event_days+' days deleted',ke:v.ke,time:moment()}) + } + }) + }else{ + callback() + } +} +//check for temporary files (special archive) +cronDeleteOldFileBins=function(v,callback){ + if(!v.d.fileBin_days||v.d.fileBin_days==''){v.d.fileBin_days=10}else{v.d.fileBin_days=parseFloat(v.d.fileBin_days)}; + if(config.cron.deleteFileBins===true&&v.d.fileBin_days!==0){ + var fileBinQuery = ' FROM Files WHERE ke=? AND `date` < DATE_SUB(NOW(), INTERVAL ? DAY)'; + sql.query("SELECT *"+fileBinQuery,[v.ke,v.d.fileBin_days],function(err,files){ + if(files&&files[0]){ + //delete the files + files.forEach(function(file){ + fs.unlink(module.exports.getFileBinDirectory(file)+file.name,function(err){ +// if(err)console.error(err) + }) + }) + //delete the database rows + sql.query("DELETE"+fileBinQuery,[v.ke,v.d.fileBin_days],function(err,rrr){ + callback() + if(err)return console.error(err); + if(rrr.affectedRows.length>0){ + module.exports.cx({f:'deleteFileBins',msg:rrr.affectedRows+' files older than '+v.d.fileBin_days+' days deleted',ke:v.ke,time:moment()}) + } + }) + }else{ + callback() + } + }) + }else{ + callback() + } +} +//check for files with no database row +cronCheckForOrphanedFiles=function(v,callback){ + if(config.cron.deleteOrphans===true){ + var finish=function(count){ + if(count>0){ + module.exports.cx({f:'deleteOrphanedFiles',msg:count+' SQL rows with no database row deleted',ke:v.ke,time:moment()}) + } + callback() + } + e={}; + var numberOfItems = 0; + sql.query('SELECT * FROM Monitors WHERE ke=?',[v.ke],function(arr,b) { + if(b&&b[0]){ + b.forEach(function(mon,m){ + fs.readdir(module.exports.getVideoDirectory(mon), function(err, items) { + e.query=[]; + e.filesFound=[mon.ke,mon.mid]; + numberOfItems+=items.length; + if(items&&items.length>0){ + items.forEach(function(v,n){ + e.query.push('time=?') + e.filesFound.push(module.exports.nameToTime(v)) + }) + sql.query('SELECT * FROM Videos WHERE ke=? AND mid=? AND ('+e.query.join(' OR ')+')',e.filesFound,function(arr,r) { + if(!r){r=[]}; + e.foundSQLrows=[]; + r.forEach(function(v,n){ + v.index=e.filesFound.indexOf(module.exports.moment(v.time,'YYYY-MM-DD HH:mm:ss')); + if(v.index>-1){ + delete(items[v.index-2]); + } + }); + items.forEach(function(v,n){ + if(v&&v!==null){ + exec('rm '+module.exports.getVideoDirectory(mon)+v); + } + if(m===b.length-1&&n===items.length-1){ + finish(numberOfItems) + } + }) + }) + }else{ + if(m===b.length-1){ + finish(numberOfItems) + } + } + }) + }); + }else{ + finish(numberOfItems) + } + }); + }else{ + callback() + } +} +//user processing function +cronProcessUser = function(number,rows){ + console.log('processUser') + var v = rows[number]; + if(!v){ + //no user object given + return + } + if(!cronAlreadyDeletedRowsWithNoVideosOnStart[v.ke]){ + cronAlreadyDeletedRowsWithNoVideosOnStart[v.ke]=false; + } + if(!cronOverlapLock[v.ke]){ + // set overlap lock + cronOverlapLock[v.ke]=true; + //set permissions + v.d=JSON.parse(v.details); + //size + if(!v.d.size||v.d.size==''){v.d.size=10000}else{v.d.size=parseFloat(v.d.size)}; + //days to keep videos + v.maxVideoDays={} + if(!v.d.days||v.d.days==''){v.d.days=5}else{v.d.days=parseFloat(v.d.days)}; + sql.query('SELECT * FROM Monitors WHERE ke=?', [v.ke], function(err,rr) { + rr.forEach(function(b,m){ + b.details=JSON.parse(b.details); + if(b.details.max_keep_days&&b.details.max_keep_days!==''){ + v.maxVideoDays[b.mid]=parseFloat(b.details.max_keep_days) + }else{ + v.maxVideoDays[b.mid]=v.d.days + }; + }) + cronDeleteOldLogs(v,function(){ + cronDeleteOldFileBins(v,function(){ + cronDeleteOldEvents(v,function(){ + cronCheckFilterRules(v,function(){ + cronDeleteRowsWithNoVideo(v,function(){ + cronCheckForOrphanedFiles(v,function(){ + //done user, unlock current, and do next + cronOverlapLock[v.ke]=false; + cronProcessUser(number+1,rows) + }) + }) + }) + }) + }) + }) + }) + } +} +//recursive function +var cronTimeout; +cronStart = function(){ + clearTimeout(cronTimeout); + x={}; + module.exports.cx({f:'start',time:moment()}) + sql.query('SELECT ke,uid,details,mail FROM Users WHERE details NOT LIKE \'%"sub"%\'', function(err,rows) { + if(err){ + console.error(err) + } + if(rows&&rows[0]){ + cronProcessUser(0,rows) + } + }) + cronTimeout=setTimeout(function(){ + cronStart(); + },parseFloat(config.cron.interval)*60000*60) +} +cronStop = function(){ + clearTimeout(cronTimeout); +} +//socket commander +io.on('f',function(d){ + switch(d.f){ + case'start':case'restart': + cronStart(); + break; + case'stop': + cronStop(); + break; + } +}) +console.log('Shinobi : cron.js loaded') +module.exports = { + begin:cronStart, + start:cronStart, + restart:cronStart, + stop:cronStop, + end:cronStop, + kill:cronStop +} \ No newline at end of file diff --git a/tools/ffmpegToWeb.rar b/tools/ffmpegToWeb.rar new file mode 100644 index 0000000000000000000000000000000000000000..7338586dada83f5045e59fedcbaea6582e0e699d GIT binary patch literal 309545 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 ?EAU3EpPqcKE5VW+h2;tJjc$3p$o>=Y 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 + +# Broadway emscriptend h264 (broadway/Decoder.js) +* Michael Bebenita +* Alon Zakai +* Andreas Gal +* Mathieu 'p01' Henri +* Matthias 'soliton4' Behrens + +# WebGL canvas helpers +* Sam Leitch @oneam + +# AVC player inspiration +* Benjamin Xiao @urbenlegend + diff --git a/tools/ffmpegToWeb/Player/broadway/LICENSE b/tools/ffmpegToWeb/Player/broadway/LICENSE new file mode 100644 index 0000000..507f677 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/LICENSE @@ -0,0 +1,10 @@ +Copyright (c) 2016, Project Authors (see AUTHORS file) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the names of the Project Authors nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tools/ffmpegToWeb/Player/broadway/README.md b/tools/ffmpegToWeb/Player/broadway/README.md new file mode 100644 index 0000000..01556d7 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/README.md @@ -0,0 +1,11 @@ +# Motivation + +This is a very efficient h264 video player (that can run on live stream) for your browser. +You might use this with raspicam raw h264 stream. + +This is a player around [Broadway](https://github.com/mbebenita/Broadway) Decoder, with very simple API. +NAL unit (h264 frames) are split on the server side, so the client side is very simple (and allow frame skipping easily) + + +See [github sample project's page for more information](https://github.com/131/h264-live-player) + diff --git a/tools/ffmpegToWeb/Player/broadway/broadway/Decoder.js b/tools/ffmpegToWeb/Player/broadway/broadway/Decoder.js new file mode 100644 index 0000000..0a66260 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/broadway/Decoder.js @@ -0,0 +1,966 @@ +// universal module definition +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], factory); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.Decoder = factory(); + } +}(this, function () { + + var global; + + function initglobal(){ + global = this; + if (!global){ + if (typeof window != "undefined"){ + global = window; + }else if (typeof self != "undefined"){ + global = self; + }; + }; + }; + initglobal(); + + + function error(message) { + console.error(message); + console.trace(); + }; + + + function assert(condition, message) { + if (!condition) { + error(message); + }; + }; + + + return (function(){ + "use strict"; + + + + + var getModule = function(_broadwayOnHeadersDecoded, _broadwayOnPictureDecoded){ + + var window = this; + //console.log(typeof window); + + window._broadwayOnHeadersDecoded = _broadwayOnHeadersDecoded; + window._broadwayOnPictureDecoded = _broadwayOnPictureDecoded; + + var Module = { + 'print': function(text) { console.log('stdout: ' + text); }, + 'printErr': function(text) { console.log('stderr: ' + text); } + }; + + + /* + + The reason why this is all packed into one file is that this file can also function as worker. + you can integrate the file into your build system and provide the original file to be loaded into a worker. + + */ + +function d(a){throw a;}var g=void 0,i=!0,k=null,m=!1;function n(){return function(){}}var p;p||(p=eval("(function() { try { return Module || {} } catch(e) { return {} } })()"));var aa={},r;for(r in p)p.hasOwnProperty(r)&&(aa[r]=p[r]);var t="object"===typeof process&&"function"===typeof null,ba="object"===typeof window,ca="function"===typeof importScripts,da=!ba&&!t&&!ca; +if(t){p.print||(p.print=function(a){process.stdout.write(a+"\n")});p.printErr||(p.printErr=function(a){process.stderr.write(a+"\n")});var fa=(null)("fs"),ga=(null)("path");p.read=function(a,b){var a=ga.normalize(a),c=fa.readFileSync(a);!c&&a!=ga.resolve(a)&&(a=path.join(__dirname,"..","src",a),c=fa.readFileSync(a));c&&!b&&(c=c.toString());return c};p.readBinary=function(a){return p.read(a,i)};p.load=function(a){ha(read(a))};p.thisProgram=1 0) var gc = undefined")):ba||ca?(p.read=function(a){var b=new XMLHttpRequest;b.open("GET",a,m);b.send(k);return b.responseText},"undefined"!=typeof arguments&&(p.arguments=arguments),"undefined"!==typeof console?(p.print||(p.print=function(a){console.log(a)}),p.printErr||(p.printErr=function(a){console.log(a)})):p.print||(p.print= +n()),ba?window.Module=p:p.load=importScripts):d("Unknown runtime environment. Where are we?");function ha(a){eval.call(k,a)}!p.load&&p.read&&(p.load=function(a){ha(p.read(a))});p.print||(p.print=n());p.printErr||(p.printErr=p.print);p.arguments||(p.arguments=[]);p.thisProgram||(p.thisProgram="./this.program");p.print=p.print;p.fa=p.printErr;p.preRun=[];p.postRun=[];for(r in aa)aa.hasOwnProperty(r)&&(p[r]=aa[r]); +var z={Yd:function(a){ja=a},xd:function(){return ja},Tb:function(){return y},Sb:function(a){y=a},oc:function(a){switch(a){case "i1":case "i8":return 1;case "i16":return 2;case "i32":return 4;case "i64":return 8;case "float":return 4;case "double":return 8;default:return"*"===a[a.length-1]?z.ia:"i"===a[0]?(a=parseInt(a.substr(1)),w(0===a%8),a/8):0}},vd:function(a){return Math.max(z.oc(a),z.ia)},Qf:16,ng:function(a,b,c){return!c&&("i64"==a||"double"==a)?8:!a?Math.min(b,8):Math.min(b||(a?z.vd(a):0), +z.ia)},Fa:function(a,b,c){return c&&c.length?(c.splice||(c=Array.prototype.slice.call(c)),c.splice(0,0,b),p["dynCall_"+a].apply(k,c)):p["dynCall_"+a].call(k,b)},eb:[],Vc:function(a){for(var b=0;b=F&&A("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+F+", (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.");return b},ub:function(a,b){return Math.ceil(a/(b?b:16))*(b?b:16)},Fg:function(a,b,c){return c?+(a>>>0)+4294967296*+(b>>>0):+(a>>>0)+4294967296* ++(b|0)},Pc:8,ia:4,Rf:0};p.Runtime=z;z.addFunction=z.Vc;z.removeFunction=z.Sd;var H=m,la,ma,ja;function w(a,b){a||A("Assertion failed: "+b)}function na(a){var b=p["_"+a];if(!b)try{b=eval("_"+a)}catch(c){}w(b,"Cannot call unknown function "+a+" (perhaps LLVM optimizations or closure removed it?)");return b}var oa,pa; +(function(){function a(a){a=a.toString().match(e).slice(1);return{arguments:a[0],body:a[1],returnValue:a[2]}}var b={stackSave:function(){z.Tb()},stackRestore:function(){z.Sb()},arrayToC:function(a){var b=z.pb(a.length);qa(a,b);return b},stringToC:function(a){var b=0;a!==k&&(a!==g&&0!==a)&&(b=z.pb((a.length<<2)+1),ra(a,b));return b}},c={string:b.stringToC,array:b.arrayToC};pa=function(a,b,e,f){var h=na(a),s=[],a=0;if(f)for(var v=0;v>0]=b;break;case "i8":I[a>>0]=b;break;case "i16":J[a>>1]=b;break;case "i32":K[a>>2]=b;break;case "i64":ma=[b>>>0,(la=b,1<=+ta(la)?0>>0:~~+xa((la-+(~~la>>>0))/4294967296)>>>0:0)];K[a>>2]=ma[0];K[a+4>>2]=ma[1];break;case "float":ya[a>>2]=b;break;case "double":za[a>>3]=b;break;default:A("invalid type for setValue: "+c)}}p.setValue=sa; +function Aa(a,b){b=b||"i8";"*"===b.charAt(b.length-1)&&(b="i32");switch(b){case "i1":return I[a>>0];case "i8":return I[a>>0];case "i16":return J[a>>1];case "i32":return K[a>>2];case "i64":return K[a>>2];case "float":return ya[a>>2];case "double":return za[a>>3];default:A("invalid type for setValue: "+b)}return k}p.getValue=Aa;var L=2,Ba=4;p.ALLOC_NORMAL=0;p.ALLOC_STACK=1;p.ALLOC_STATIC=L;p.ALLOC_DYNAMIC=3;p.ALLOC_NONE=Ba; +function M(a,b,c,e){var f,h;"number"===typeof a?(f=i,h=a):(f=m,h=a.length);var j="string"===typeof b?b:k,c=c==Ba?e:[Ca,z.pb,z.Ec,z.bb][c===g?L:c](Math.max(h,j?1:b.length));if(f){e=c;w(0==(c&3));for(a=c+(h&-4);e>2]=0;for(a=c+h;e>0]=0;return c}if("i8"===j)return a.subarray||a.slice?N.set(a,c):N.set(new Uint8Array(a),c),c;for(var e=0,l,u;e>0];if(128<=e)c=i;else if(0==e&&!b)break;f++;if(b&&f==b)break}b||(b=f);var h="";if(!c){for(;0>0],h+=c.nb(e);return h}p.Pointer_stringify=ka;p.UTF16ToString=function(a){for(var b=0,c="";;){var e=J[a+2*b>>1];if(0==e)return c;++b;c+=String.fromCharCode(e)}}; +p.stringToUTF16=function(a,b){for(var c=0;c>1]=a.charCodeAt(c);J[b+2*a.length>>1]=0};p.UTF32ToString=function(a){for(var b=0,c="";;){var e=K[a+4*b>>2];if(0==e)return c;++b;65536<=e?(e-=65536,c+=String.fromCharCode(55296|e>>10,56320|e&1023)):c+=String.fromCharCode(e)}};p.stringToUTF32=function(a,b){for(var c=0,e=0;e=f)var h=a.charCodeAt(++e),f=65536+((f&1023)<<10)|h&1023;K[b+4*c>>2]=f;++c}K[b+4*c>>2]=0}; +function Da(a){function b(c,e,f){var e=e||Infinity,h="",j=[],s;if("N"===a[l]){l++;"K"===a[l]&&l++;for(s=[];"E"!==a[l];)if("S"===a[l]){l++;var C=a.indexOf("_",l);s.push(q[a.substring(l,C)||0]||"?");l=C+1}else if("C"===a[l])s.push(s[s.length-1]),l+=2;else{var C=parseInt(a.substr(l)),P=C.toString().length;if(!C||!P){l--;break}var sb=a.substr(l+P,C);s.push(sb);q.push(sb);l+=P+C}l++;s=s.join("::");e--;if(0===e)return c?[s]:s}else if(("K"===a[l]||x&&"L"===a[l])&&l++,C=parseInt(a.substr(l)))P=C.toString().length, +s=a.substr(l+P,C),l+=P+C;x=m;"I"===a[l]?(l++,C=b(i),P=b(i,1,i),h+=P[0]+" "+s+"<"+C.join(", ")+">"):h=s;a:for(;lO?2*O:O+16777216; +O!==F&&(p.fa("increasing TOTAL_MEMORY to "+O+" to be compliant with the asm.js spec"),F=O);w("undefined"!==typeof Int32Array&&"undefined"!==typeof Float64Array&&!!(new Int32Array(1)).subarray&&!!(new Int32Array(1)).set,"JS engine does not provide full typed array support");var Q=new ArrayBuffer(F);I=new Int8Array(Q);J=new Int16Array(Q);K=new Int32Array(Q);N=new Uint8Array(Q);Ga=new Uint16Array(Q);Ha=new Uint32Array(Q);ya=new Float32Array(Q);za=new Float64Array(Q);K[0]=255;w(255===N[0]&&0===N[3],"Typed arrays 2 must be run on a little-endian system"); +p.HEAP=g;p.buffer=Q;p.HEAP8=I;p.HEAP16=J;p.HEAP32=K;p.HEAPU8=N;p.HEAPU16=Ga;p.HEAPU32=Ha;p.HEAPF32=ya;p.HEAPF64=za;function Na(a){for(;0>0]=a[c],c+=1}p.writeStringToMemory=ra;function qa(a,b){for(var c=0;c>0]=a[c]}p.writeArrayToMemory=qa; +p.writeAsciiToMemory=function(a,b,c){for(var e=0;e>0]=a.charCodeAt(e);c||(I[b+a.length>>0]=0)};if(!Math.imul||-5!==Math.imul(4294967295,5))Math.imul=function(a,b){var c=a&65535,e=b&65535;return c*e+((a>>>16)*e+c*(b>>>16)<<16)|0};Math.vg=Math.imul;var ta=Math.abs,xa=Math.ceil,wa=Math.floor,va=Math.min,S=0,Wa=k,Xa=k;function Ya(){S++;p.monitorRunDependencies&&p.monitorRunDependencies(S)}p.addRunDependency=Ya; +function Za(){S--;p.monitorRunDependencies&&p.monitorRunDependencies(S);if(0==S&&(Wa!==k&&(clearInterval(Wa),Wa=k),Xa)){var a=Xa;Xa=k;a()}}p.removeRunDependency=Za;p.preloadedImages={};p.preloadedAudios={};var T=k,Ia=8,D=Ia+7808;R.push(); +M([0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,0,0,0,0,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,0,0,0,0,10,0,0,0,13,0,0,0,16,0,0,0,11,0,0,0,14,0,0,0,18,0,0,0,13,0,0,0,16,0,0,0,20,0,0,0,14,0,0,0,18,0,0,0,23,0,0,0,16,0,0,0,20,0,0,0,25,0,0,0,18,0,0,0,23,0,0,0,29,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0, +0,0,14,0,0,0,15,0,0,0,16,0,0,0,17,0,0,0,18,0,0,0,19,0,0,0,20,0,0,0,21,0,0,0,22,0,0,0,23,0,0,0,24,0,0,0,25,0,0,0,26,0,0,0,27,0,0,0,28,0,0,0,29,0,0,0,29,0,0,0,30,0,0,0,31,0,0,0,32,0,0,0,32,0,0,0,33,0,0,0,34,0,0,0,34,0,0,0,35,0,0,0,35,0,0,0,36,0,0,0,36,0,0,0,37,0,0,0,37,0,0,0,37,0,0,0,38,0,0,0,38,0,0,0,38,0,0,0,39,0,0,0,39,0,0,0,39,0,0,0,39,0,0,0,1,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,16,0,0,0,32,0,0,0,64,0,0,0,128,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,1,0,0,0,4,0,0, +0,5,0,0,0,2,0,0,0,3,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,12,0,0,0,13,0,0,0,10,0,0,0,11,0,0,0,14,0,0,0,15,0,0,0,47,31,15,0,23,27,29,30,7,11,13,14,39,43,45,46,16,3,5,10,12,19,21,26,28,35,37,42,44,1,2,4,8,17,18,20,24,6,9,22,25,32,33,34,36,40,38,41,0,16,1,2,4,8,32,3,5,10,12,15,47,7,11,13,14,6,9,31,35,37,42,44,33,34,36,40,39,43,45,46,17,18,20,24,19,21,26,28,23,27,29,30,22,25,38,41,17,1,0,0,0,0,0,0,34,18,1,1,0,0,0,0,50,34,18,2,0,0,0,0,67,51,34,34,18,18,2,2,83,67,51,35,18,18,2,2,19,35,67,51,99,83,2,2,0, +0,101,85,68,68,52,52,35,35,35,35,19,19,19,19,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,249,233,217,200,200,184,184,167,167,167,167,151,151,151,151,134,134,134,134,134,134,134,134,118,118,118,118,118,118,118,118,230,214,198,182,165,165,149,149,132,132,132,132,116,116,116,116,100,100,100,100,84,84,84,84,67,67,67,67,67,67,67,67,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,19,19,19,19,19,19,19,19,3,3,3,3,3,3,3,3,214,182,197,197,165,165,149,149,132,132,132,132,84,84,84,84,68,68,68,68,4,4,4,4,115,115,115,115, +115,115,115,115,99,99,99,99,99,99,99,99,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,19,19,19,19,19,19,19,19,197,181,165,5,148,148,116,116,52,52,36,36,131,131,131,131,99,99,99,99,83,83,83,83,67,67,67,67,19,19,19,19,181,149,164,164,132,132,36,36,20,20,4,4,115,115,115,115,99,99,99,99,83,83,83,83,67,67,67,67,51,51,51,51,166,6,21,21,132,132,132,132,147,147,147,147,147,147,147,147,115,115,115,115,115,115,115,115,99,99,99,99,99,99,99,99,83,83,83,83,83,83,83,83,67,67,67,67,67,67,67,67,51,51,51,51,51, +51,51,51,35,35,35,35,35,35,35,35,150,6,21,21,116,116,116,116,131,131,131,131,131,131,131,131,99,99,99,99,99,99,99,99,67,67,67,67,67,67,67,67,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,134,6,37,37,20,20,20,20,115,115,115,115,115,115,115,115,99,99,99,99,99,99,99,99,51,51,51,51,51,51,51,51,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,22,6,117,117,36,36,36,36,83,83,83,83,83,83,83,83,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,21,5,100,100,35,35,35,35,82,82,82,82,82,82,82,82,66,66,66,66,66,66,66,66,50,50,50,50,50,50,50,50,4,20,35,35,51,51,83,83,65,65,65,65,65,65,65,65,4,20,67,67,34,34,34,34,49,49,49,49,49,49,49,49,3,19,50,50,33,33,33,33,2,18,33,33,0,0,0,0,0,0,0,0,0,0,102,32,38,16,6,8,101,24,101,24,67,16,67,16,67,16,67,16,67,16,67,16,67,16,67,16,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34, +8,34,8,34,8,34,8,34,8,34,8,34,8,0,0,0,0,0,0,0,0,106,64,74,48,42,40,10,32,105,56,105,56,73,40,73,40,41,32,41,32,9,24,9,24,104,48,104,48,104,48,104,48,72,32,72,32,72,32,72,32,40,24,40,24,40,24,40,24,8,16,8,16,8,16,8,16,103,40,103,40,103,40,103,40,103,40,103,40,103,40,103,40,71,24,71,24,71,24,71,24,71,24,71,24,71,24,71,24,110,96,78,88,46,80,14,80,110,88,78,80,46,72,14,72,13,64,13,64,77,72,77,72,45,64,45,64,13,56,13,56,109,80,109,80,77,64,77,64,45,56,45,56,13,48,13,48,107,72,107,72,107,72,107,72,107, +72,107,72,107,72,107,72,75,56,75,56,75,56,75,56,75,56,75,56,75,56,75,56,43,48,43,48,43,48,43,48,43,48,43,48,43,48,43,48,11,40,11,40,11,40,11,40,11,40,11,40,11,40,11,40,0,0,0,0,47,104,47,104,16,128,80,128,48,128,16,120,112,128,80,120,48,120,16,112,112,120,80,112,48,112,16,104,111,112,111,112,79,104,79,104,47,96,47,96,15,96,15,96,111,104,111,104,79,96,79,96,47,88,47,88,15,88,15,88,0,0,0,0,0,0,0,0,102,56,70,32,38,32,6,16,102,48,70,24,38,24,6,8,101,40,101,40,37,16,37,16,100,32,100,32,100,32,100,32,100, +24,100,24,100,24,100,24,67,16,67,16,67,16,67,16,67,16,67,16,67,16,67,16,0,0,0,0,0,0,0,0,105,72,73,56,41,56,9,48,8,40,8,40,72,48,72,48,40,48,40,48,8,32,8,32,103,64,103,64,103,64,103,64,71,40,71,40,71,40,71,40,39,40,39,40,39,40,39,40,7,24,7,24,7,24,7,24,0,0,0,0,109,120,109,120,110,128,78,128,46,128,14,128,46,120,14,120,78,120,46,112,77,112,77,112,13,112,13,112,109,112,109,112,77,104,77,104,45,104,45,104,13,104,13,104,109,104,109,104,77,96,77,96,45,96,45,96,13,96,13,96,12,88,12,88,12,88,12,88,76,88, +76,88,76,88,76,88,44,88,44,88,44,88,44,88,12,80,12,80,12,80,12,80,108,96,108,96,108,96,108,96,76,80,76,80,76,80,76,80,44,80,44,80,44,80,44,80,12,72,12,72,12,72,12,72,107,88,107,88,107,88,107,88,107,88,107,88,107,88,107,88,75,72,75,72,75,72,75,72,75,72,75,72,75,72,75,72,43,72,43,72,43,72,43,72,43,72,43,72,43,72,43,72,11,64,11,64,11,64,11,64,11,64,11,64,11,64,11,64,107,80,107,80,107,80,107,80,107,80,107,80,107,80,107,80,75,64,75,64,75,64,75,64,75,64,75,64,75,64,75,64,43,64,43,64,43,64,43,64,43,64,43, +64,43,64,43,64,11,56,11,56,11,56,11,56,11,56,11,56,11,56,11,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,24,70,56,38,56,6,16,102,72,70,48,38,48,6,8,37,40,37,40,69,40,69,40,37,32,37,32,69,32,69,32,37,24,37,24,101,64,101,64,69,24,69,24,37,16,37,16,100,56,100,56,100,56,100,56,100,48,100,48,100,48,100,48,100,40,100,40,100,40,100,40,100,32,100,32,100,32,100,32,100,24,100,24,100,24,100,24,68,16,68,16,68,16,68,16,36,8,36,8,36,8,36,8,4,0,4,0,4,0,4,0,0,0,10,128,106,128,74,128,42,128,10,120,106,120,74,120,42,120,10, +112,106,112,74,112,42,112,10,104,41,104,41,104,9,96,9,96,73,104,73,104,41,96,41,96,9,88,9,88,105,104,105,104,73,96,73,96,41,88,41,88,9,80,9,80,104,96,104,96,104,96,104,96,72,88,72,88,72,88,72,88,40,80,40,80,40,80,40,80,8,72,8,72,8,72,8,72,104,88,104,88,104,88,104,88,72,80,72,80,72,80,72,80,40,72,40,72,40,72,40,72,8,64,8,64,8,64,8,64,7,56,7,56,7,56,7,56,7,56,7,56,7,56,7,56,7,48,7,48,7,48,7,48,7,48,7,48,7,48,7,48,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,7,40,7,40,7,40,7,40,7,40,7,40,7,40,7,40, +103,80,103,80,103,80,103,80,103,80,103,80,103,80,103,80,71,64,71,64,71,64,71,64,71,64,71,64,71,64,71,64,39,64,39,64,39,64,39,64,39,64,39,64,39,64,39,64,7,32,7,32,7,32,7,32,7,32,7,32,7,32,7,32,6,8,38,8,0,0,6,0,6,16,38,16,70,16,0,0,6,24,38,24,70,24,102,24,6,32,38,32,70,32,102,32,6,40,38,40,70,40,102,40,6,48,38,48,70,48,102,48,6,56,38,56,70,56,102,56,6,64,38,64,70,64,102,64,6,72,38,72,70,72,102,72,6,80,38,80,70,80,102,80,6,88,38,88,70,88,102,88,6,96,38,96,70,96,102,96,6,104,38,104,70,104,102,104,6,112, +38,112,70,112,102,112,6,120,38,120,70,120,102,120,6,128,38,128,70,128,102,128,0,0,67,16,2,0,2,0,33,8,33,8,33,8,33,8,103,32,103,32,72,32,40,32,71,24,71,24,39,24,39,24,6,32,6,32,6,32,6,32,6,24,6,24,6,24,6,24,6,16,6,16,6,16,6,16,102,24,102,24,102,24,102,24,38,16,38,16,38,16,38,16,6,8,6,8,6,8,6,8,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,3, +0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,3,0,0,0,19,0,0,0,1,0,0,0,18,0,0,0,0,0,0,0,17,0,0,0,4,0,0,0,16,0,0,0,3,0,0,0,23,0,0,0,1,0,0,0,22,0,0,0,0,0,0,0,21,0,0,0,4,0,0,0,20,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,4,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,12,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,4,0,0,0,13,0,0,0,255,0,0,0,8,0,0,0,1,0,0,0,19,0,0,0,2,0,0,0,18,0,0,0,4,0, +0,0,17,0,0,0,255,0,0,0,16,0,0,0,1,0,0,0,23,0,0,0,2,0,0,0,22,0,0,0,4,0,0,0,21,0,0,0,255,0,0,0,20,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,13,0,0,0,1,0,0,0,18,0,0,0,1,0,0,0,19,0,0,0,4,0,0,0,16,0,0,0,4,0,0,0,17,0,0,0,1,0,0,0,22,0,0,0,1,0,0,0,23,0,0,0,4,0,0,0,20,0,0,0,4,0,0,0,21,0,0,0,0, +0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,15,0,0,0,4,0,0,0,10,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,11,0,0,0,4,0,0,0,14,0,0,0,0,0,0,0,17,0,0,0,4,0,0,0,16,0,0,0,0,0,0,0,19,0,0,0,4,0,0,0,18,0,0,0,0,0,0,0,21,0,0,0,4,0,0,0,20,0,0,0,0,0,0,0,23,0,0,0,4,0,0,0,22,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,12,0,0,0,8,0,0,0,12,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0, +12,0,0,0,8,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,8,0,0,0,8,0,0,0,12,0,0,0,12,0,0,0,8,0,0,0,8,0,0,0,12,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108, +109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234, +235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,0,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,1,0,0,0,255,0, +0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,13,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0, +0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,4,0,0,0,2,0,0,0,10,0,0, +0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,2,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0, +0,0,4,0,0,0,9,0,0,0,255,0,0,0,12,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,4,0,0,0,13,0,0,0,255,0,0,0,8,0,0,0,1,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,4,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,255,0, +0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0, +0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,13,0,0,0,0,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0, +0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,13,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0, +0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,15,0,0,0,4,0,0,0,10,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,11,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,11,0,0,0,4,0,0,0,14,0,0, +0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0,0,0,14,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,5,6,7,8,9,10,12,13,15,17,20,22,25,28,32,36,40,45,50,56,63,71,80,90,101,113,127,144,162,182,203,226,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,3,4,4,4,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,1,1,2,1,1,2,1,2,3,1,2,3,2,2,3,2,2,4,2,3,4,2,3,4,3,3,5,3,4,6,3,4,6,4,5,7,4,5,8,4,6,9,5,7,10,6,8,11,6,8,13,7,10,14,8,11,16,9,12,18,10,13,20,11,15,23,13,17,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,69,67,79,68,69,82,32,73,78,73,84,73,65,76,73,90,65,84,73,79,78,32,70,65,73,76,69,68,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"i8",Ba,z.Pc);var $a=z.ub(M(12,"i8",L),8);w(0==$a%8); +var U={O:1,Q:2,Ef:3,De:4,ha:5,Zb:6,be:7,$e:8,V:9,oe:10,Ca:11,Of:11,Mc:12,qb:13,ye:14,mf:15,ga:16,Xb:17,Oc:18,Qa:19,Sa:20,pa:21,B:22,Ve:23,Lc:24,Nc:25,Lf:26,ze:27,hf:28,Ua:29,Bf:30,Oe:31,uf:32,ve:33,yf:34,df:42,Be:43,pe:44,Fe:45,Ge:46,He:47,Ne:48,Mf:49,Ye:50,Ee:51,te:35,af:37,ge:52,je:53,Pf:54,We:55,ke:56,le:57,ue:35,me:59,kf:60,Ze:61,If:62,jf:63,ef:64,ff:65,Af:66,bf:67,ee:68,Ff:69,qe:70,vf:71,Qe:72,we:73,ie:74,qf:76,he:77,zf:78,Ie:79,Je:80,Me:81,Le:82,Ke:83,lf:38,sb:39,Re:36,rb:40,Ta:95,tf:96,se:104, +Xe:105,fe:97,xf:91,of:88,gf:92,Cf:108,Wb:111,ce:98,re:103,Ue:101,Se:100,Jf:110,Ae:112,Yb:113,Jc:115,Hc:114,Ic:89,Pe:90,wf:93,Df:94,de:99,Te:102,Kc:106,Ra:107,Kf:109,Nf:87,xe:122,Gf:116,pf:95,cf:123,Ce:84,rf:75,ne:125,nf:131,sf:130,Hf:86},ab={"0":"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes", +12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func", +34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange", +53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)", +74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required", +90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected", +107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"},bb=0;function V(a){return K[bb>>2]=a} +function cb(a,b){for(var c=0,e=a.length-1;0<=e;e--){var f=a[e];"."===f?a.splice(e,1):".."===f?(a.splice(e,1),c++):c&&(a.splice(e,1),c--)}if(b)for(;c--;c)a.unshift("..");return a}function db(a){var b="/"===a.charAt(0),c="/"===a.substr(-1),a=cb(a.split("/").filter(function(a){return!!a}),!b).join("/");!a&&!b&&(a=".");a&&c&&(a+="/");return(b?"/":"")+a} +function eb(a){var b=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(a).slice(1),a=b[0],b=b[1];if(!a&&!b)return".";b&&(b=b.substr(0,b.length-1));return a+b}function W(a){if("/"===a)return"/";var b=a.lastIndexOf("/");return-1===b?a:a.substr(b+1)}function fb(){var a=Array.prototype.slice.call(arguments,0);return db(a.join("/"))}function X(a,b){return db(a+"/"+b)} +function gb(){for(var a="",b=m,c=arguments.length-1;-1<=c&&!b;c--){b=0<=c?arguments[c]:B.yb();"string"!==typeof b&&d(new TypeError("Arguments to path.resolve must be strings"));if(!b)return"";a=b+"/"+a;b="/"===b.charAt(0)}a=cb(a.split("/").filter(function(a){return!!a}),!b).join("/");return(b?"/":"")+a||"."} +function hb(a,b){function c(a){for(var b=0;bc?[]:a.slice(b,c-b+1)}for(var a=gb(a).substr(1),b=gb(b).substr(1),e=c(a.split("/")),f=c(b.split("/")),h=Math.min(e.length,f.length),j=h,l=0;la.k.length)&&(a.k=Y.ud(a),a.q=a.k.length);if(!a.k||a.k.subarray){var c=a.k?a.k.buffer.byteLength:0;c>=b||(b=Math.max(b,c*(1048576>c?2:1.125)|0),0!=c&&(b=Math.max(b,256)),c=a.k,a.k=new Uint8Array(b),0b)a.k.length=b;else for(;a.k.length=a.g.q)return 0;a=Math.min(a.g.q-f,e);w(0<=a);if(8b&&d(new B.e(U.B));return b},Ea:function(a,b,c){Y.lc(a.g,b+c);a.g.q=Math.max(a.g.q,b+c)},Ja:function(a,b,c,e,f,h,j){B.isFile(a.g.mode)||d(new B.e(U.Qa));c=a.g.k;if(!(j&2)&&(c.buffer===b||c.buffer=== +b.buffer))a=m,e=c.byteOffset;else{if(0>>0)%B.T.length},tc:function(a){var b=B.Fb(a.parent.id,a.name);a.ma=B.T[b];B.T[b]=a},uc:function(a){var b=B.Fb(a.parent.id,a.name);if(B.T[b]===a)B.T[b]=a.ma;else for(b=B.T[b];b;){if(b.ma===a){b.ma=a.ma;break}b=b.ma}},aa:function(a,b){var c=B.Gd(a);c&&d(new B.e(c,a));for(c=B.T[B.Fb(a.id,b)];c;c=c.ma){var e=c.name;if(c.parent.id===a.id&&e===b)return c}return B.ra(a,b)},createNode:function(a,b,c,e){B.Va||(B.Va=function(a,b,c,e){a|| +(a=this);this.parent=a;this.F=a.F;this.Ka=k;this.id=B.Jd++;this.name=b;this.mode=c;this.n={};this.p={};this.ob=e},B.Va.prototype={},Object.defineProperties(B.Va.prototype,{M:{get:function(){return 365===(this.mode&365)},set:function(a){a?this.mode|=365:this.mode&=-366}},write:{get:function(){return 146===(this.mode&146)},set:function(a){a?this.mode|=146:this.mode&=-147}},Dd:{get:function(){return B.J(this.mode)}},Gb:{get:function(){return B.ib(this.mode)}}}));a=new B.Va(a,b,c,e);B.tc(a);return a}, +zb:function(a){B.uc(a)},jb:function(a){return a===a.parent},ka:function(a){return!!a.Ka},isFile:function(a){return 32768===(a&61440)},J:function(a){return 16384===(a&61440)},Ia:function(a){return 40960===(a&61440)},ib:function(a){return 8192===(a&61440)},Bd:function(a){return 24576===(a&61440)},Cd:function(a){return 4096===(a&61440)},Ed:function(a){return 49152===(a&49152)},rd:{r:0,rs:1052672,"r+":2,w:577,wx:705,xw:705,"w+":578,"wx+":706,"xw+":706,a:1089,ax:1217,xa:1217,"a+":1090,"ax+":1218,"xa+":1218}, +wc:function(a){var b=B.rd[a];"undefined"===typeof b&&d(Error("Unknown file open mode: "+a));return b},sd:function(a){var b=["r","w","rw"][a&2097155];a&512&&(b+="w");return b},na:function(a,b){return B.vc?0:-1!==b.indexOf("r")&&!(a.mode&292)||-1!==b.indexOf("w")&&!(a.mode&146)||-1!==b.indexOf("x")&&!(a.mode&73)?U.qb:0},Gd:function(a){var b=B.na(a,"x");return b?b:!a.n.ra?U.qb:0},Jb:function(a,b){try{return B.aa(a,b),U.Xb}catch(c){}return B.na(a,"wx")},kb:function(a,b,c){var e;try{e=B.aa(a,b)}catch(f){return f.cb}if(a= +B.na(a,"wx"))return a;if(c){if(!B.J(e.mode))return U.Sa;if(B.jb(e)||B.da(e)===B.yb())return U.ga}else if(B.J(e.mode))return U.pa;return 0},Hd:function(a,b){return!a?U.Q:B.Ia(a.mode)?U.rb:B.J(a.mode)&&(0!==(b&2097155)||b&512)?U.pa:B.na(a,B.sd(b))},Qc:4096,Kd:function(a,b){for(var b=b||B.Qc,c=a||0;c<=b;c++)if(!B.oa[c])return c;d(new B.e(U.Lc))},qa:function(a){return B.oa[a]},fc:function(a,b,c){B.Wa||(B.Wa=n(),B.Wa.prototype={},Object.defineProperties(B.Wa.prototype,{object:{get:function(){return this.g}, +set:function(a){this.g=a}},yg:{get:function(){return 1!==(this.D&2097155)}},zg:{get:function(){return 0!==(this.D&2097155)}},xg:{get:function(){return this.D&1024}}}));var e=new B.Wa,f;for(f in a)e[f]=a[f];a=e;b=B.Kd(b,c);a.C=b;return B.oa[b]=a},dd:function(a){B.oa[a]=k},pc:function(a){return B.oa[a-1]},Eb:function(a){return a?a.C+1:0},bd:{open:function(a){a.p=B.td(a.g.ob).p;a.p.open&&a.p.open(a)},$:function(){d(new B.e(U.Ua))}},Ib:function(a){return a>>8},Gg:function(a){return a&255},la:function(a, +b){return a<<8|b},Ob:function(a,b){B.ic[a]={p:b}},td:function(a){return B.ic[a]},nc:function(a){for(var b=[],a=[a];a.length;){var c=a.pop();b.push(c);a.push.apply(a,c.La)}return b},Fc:function(a,b){function c(a){if(a){if(!c.pd)return c.pd=i,b(a)}else++f>=e.length&&b(k)}"function"===typeof a&&(b=a,a=m);var e=B.nc(B.root.F),f=0;e.forEach(function(b){if(!b.type.Fc)return c(k);b.type.Fc(b,a,c)})},F:function(a,b,c){var e="/"===c,f=!c,h;e&&B.root&&d(new B.e(U.ga));!e&&!f&&(h=B.u(c,{Bb:m}),c=h.path,h=h.g, +B.ka(h)&&d(new B.e(U.ga)),B.J(h.mode)||d(new B.e(U.Sa)));b={type:a,Kg:b,Id:c,La:[]};a=a.F(b);a.F=b;b.root=a;e?B.root=a:h&&(h.Ka=b,h.F&&h.F.La.push(b));return a},Qg:function(a){a=B.u(a,{Bb:m});B.ka(a.g)||d(new B.e(U.B));var a=a.g,b=a.Ka,c=B.nc(b);Object.keys(B.T).forEach(function(a){for(a=B.T[a];a;){var b=a.ma;-1!==c.indexOf(a.F)&&B.zb(a);a=b}});a.Ka=k;b=a.F.La.indexOf(b);w(-1!==b);a.F.La.splice(b,1)},ra:function(a,b){return a.n.ra(a,b)},ba:function(a,b,c){var e=B.u(a,{parent:i}).g,a=W(a);(!a||"."=== +a||".."===a)&&d(new B.e(U.B));var f=B.Jb(e,a);f&&d(new B.e(f));e.n.ba||d(new B.e(U.O));return e.n.ba(e,a,b,c)},create:function(a,b){b=(b!==g?b:438)&4095;b|=32768;return B.ba(a,b,0)},ea:function(a,b){b=(b!==g?b:511)&1023;b|=16384;return B.ba(a,b,0)},lb:function(a,b,c){"undefined"===typeof c&&(c=b,b=438);return B.ba(a,b|8192,c)},ca:function(a,b){gb(a)||d(new B.e(U.Q));var c=B.u(b,{parent:i}).g;c||d(new B.e(U.Q));var e=W(b),f=B.Jb(c,e);f&&d(new B.e(f));c.n.ca||d(new B.e(U.O));return c.n.ca(c,e,a)},rename:function(a, +b){var c=eb(a),e=eb(b),f=W(a),h=W(b),j,l,u;try{j=B.u(a,{parent:i}),l=j.g,j=B.u(b,{parent:i}),u=j.g}catch(q){d(new B.e(U.ga))}(!l||!u)&&d(new B.e(U.Q));l.F!==u.F&&d(new B.e(U.Oc));j=B.aa(l,f);e=hb(a,e);"."!==e.charAt(0)&&d(new B.e(U.B));e=hb(b,c);"."!==e.charAt(0)&&d(new B.e(U.sb));var x;try{x=B.aa(u,h)}catch(s){}if(j!==x){c=B.J(j.mode);(f=B.kb(l,f,c))&&d(new B.e(f));(f=x?B.kb(u,h,c):B.Jb(u,h))&&d(new B.e(f));l.n.rename||d(new B.e(U.O));(B.ka(j)||x&&B.ka(x))&&d(new B.e(U.ga));u!==l&&(f=B.na(l,"w"))&& +d(new B.e(f));try{B.H.willMovePath&&B.H.willMovePath(a,b)}catch(v){console.log("FS.trackingDelegate['willMovePath']('"+a+"', '"+b+"') threw an exception: "+v.message)}B.uc(j);try{l.n.rename(j,u,h)}catch(G){d(G)}finally{B.tc(j)}try{if(B.H.onMovePath)B.H.onMovePath(a,b)}catch(ua){console.log("FS.trackingDelegate['onMovePath']('"+a+"', '"+b+"') threw an exception: "+ua.message)}}},Oa:function(a){var b=B.u(a,{parent:i}).g,c=W(a),e=B.aa(b,c),f=B.kb(b,c,i);f&&d(new B.e(f));b.n.Oa||d(new B.e(U.O));B.ka(e)&& +d(new B.e(U.ga));try{B.H.willDeletePath&&B.H.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.n.Oa(b,c);B.zb(e);try{if(B.H.onDeletePath)B.H.onDeletePath(a)}catch(j){console.log("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+j.message)}},Na:function(a){a=B.u(a,{R:i}).g;a.n.Na||d(new B.e(U.Sa));return a.n.Na(a)},za:function(a){var b=B.u(a,{parent:i}).g,c=W(a),e=B.aa(b,c),f=B.kb(b,c,m);f&&(f===U.pa&&(f=U.O), +d(new B.e(f)));b.n.za||d(new B.e(U.O));B.ka(e)&&d(new B.e(U.ga));try{B.H.willDeletePath&&B.H.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.n.za(b,c);B.zb(e);try{if(B.H.onDeletePath)B.H.onDeletePath(a)}catch(j){console.log("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+j.message)}},ta:function(a){(a=B.u(a).g)||d(new B.e(U.Q));a.n.ta||d(new B.e(U.B));return a.n.ta(a)},Dc:function(a,b){var c=B.u(a,{R:!b}).g; +c||d(new B.e(U.Q));c.n.S||d(new B.e(U.O));return c.n.S(c)},Eg:function(a){return B.Dc(a,i)},Ya:function(a,b,c){a="string"===typeof a?B.u(a,{R:!c}).g:a;a.n.I||d(new B.e(U.O));a.n.I(a,{mode:b&4095|a.mode&-4096,timestamp:Date.now()})},Bg:function(a,b){B.Ya(a,b,i)},jg:function(a,b){var c=B.qa(a);c||d(new B.e(U.V));B.Ya(c.g,b)},dc:function(a,b,c,e){a="string"===typeof a?B.u(a,{R:!e}).g:a;a.n.I||d(new B.e(U.O));a.n.I(a,{timestamp:Date.now()})},Cg:function(a,b,c){B.dc(a,b,c,i)},kg:function(a,b,c){(a=B.qa(a))|| +d(new B.e(U.V));B.dc(a.g,b,c)},truncate:function(a,b){0>b&&d(new B.e(U.B));var c;c="string"===typeof a?B.u(a,{R:i}).g:a;c.n.I||d(new B.e(U.O));B.J(c.mode)&&d(new B.e(U.pa));B.isFile(c.mode)||d(new B.e(U.B));var e=B.na(c,"w");e&&d(new B.e(e));c.n.I(c,{size:b,timestamp:Date.now()})},mg:function(a,b){var c=B.qa(a);c||d(new B.e(U.V));0===(c.D&2097155)&&d(new B.e(U.B));B.truncate(c.g,b)},Rg:function(a,b,c){a=B.u(a,{R:i}).g;a.n.I(a,{timestamp:Math.max(b,c)})},open:function(a,b,c,e,f){""===a&&d(new B.e(U.Q)); +var b="string"===typeof b?B.wc(b):b,c=b&64?("undefined"===typeof c?438:c)&4095|32768:0,h;if("object"===typeof a)h=a;else{a=db(a);try{h=B.u(a,{R:!(b&131072)}).g}catch(j){}}var l=m;b&64&&(h?b&128&&d(new B.e(U.Xb)):(h=B.ba(a,c,0),l=i));h||d(new B.e(U.Q));B.ib(h.mode)&&(b&=-513);l||(c=B.Hd(h,b))&&d(new B.e(c));b&512&&B.truncate(h,0);b&=-641;e=B.fc({g:h,path:B.da(h),D:b,seekable:i,position:0,p:h.p,$d:[],error:m},e,f);e.p.open&&e.p.open(e);p.logReadFiles&&!(b&1)&&(B.Mb||(B.Mb={}),a in B.Mb||(B.Mb[a]=1, +p.printErr("read file: "+a)));try{B.H.onOpenFile&&(f=0,1!==(b&2097155)&&(f|=B.Gc.yc.Rc),0!==(b&2097155)&&(f|=B.Gc.yc.Sc),B.H.onOpenFile(a,f))}catch(u){console.log("FS.trackingDelegate['onOpenFile']('"+a+"', flags) threw an exception: "+u.message)}return e},close:function(a){try{a.p.close&&a.p.close(a)}catch(b){d(b)}finally{B.dd(a.C)}},$:function(a,b,c){(!a.seekable||!a.p.$)&&d(new B.e(U.Ua));a.position=a.p.$(a,b,c);a.$d=[];return a.position},M:function(a,b,c,e,f){(0>e||0>f)&&d(new B.e(U.B));1===(a.D& +2097155)&&d(new B.e(U.V));B.J(a.g.mode)&&d(new B.e(U.pa));a.p.M||d(new B.e(U.B));var h=i;"undefined"===typeof f?(f=a.position,h=m):a.seekable||d(new B.e(U.Ua));b=a.p.M(a,b,c,e,f);h||(a.position+=b);return b},write:function(a,b,c,e,f,h){(0>e||0>f)&&d(new B.e(U.B));0===(a.D&2097155)&&d(new B.e(U.V));B.J(a.g.mode)&&d(new B.e(U.pa));a.p.write||d(new B.e(U.B));a.D&1024&&B.$(a,0,2);var j=i;"undefined"===typeof f?(f=a.position,j=m):a.seekable||d(new B.e(U.Ua));b=a.p.write(a,b,c,e,f,h);j||(a.position+=b); +try{if(a.path&&B.H.onWriteToFile)B.H.onWriteToFile(a.path)}catch(l){console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: "+l.message)}return b},Ea:function(a,b,c){(0>b||0>=c)&&d(new B.e(U.B));0===(a.D&2097155)&&d(new B.e(U.V));!B.isFile(a.g.mode)&&!B.J(node.mode)&&d(new B.e(U.Qa));a.p.Ea||d(new B.e(U.Ta));a.p.Ea(a,b,c)},Ja:function(a,b,c,e,f,h,j){1===(a.D&2097155)&&d(new B.e(U.qb));a.p.Ja||d(new B.e(U.Qa));return a.p.Ja(a,b,c,e,f,h,j)},Ha:function(a,b,c){a.p.Ha||d(new B.e(U.Nc)); +return a.p.Ha(a,b,c)},Mg:function(a,b){b=b||{};b.D=b.D||"r";b.encoding=b.encoding||"binary";"utf8"!==b.encoding&&"binary"!==b.encoding&&d(Error('Invalid encoding type "'+b.encoding+'"'));var c,e=B.open(a,b.D),f=B.Dc(a).size,h=new Uint8Array(f);B.M(e,h,0,f,0);if("utf8"===b.encoding){c="";for(var j=new z.Da,l=0;l>2]=B.Eb(a);w(0===a.C,"invalid handle for stdin ("+a.C+")");a=B.open("/dev/stdout","w");K[pb>>2]=B.Eb(a);w(1===a.C,"invalid handle for stdout ("+a.C+")");a=B.open("/dev/stderr","w");K[qb>>2]=B.Eb(a);w(2===a.C,"invalid handle for stderr ("+a.C+")")},jc:function(){B.e||(B.e=function(a,b){this.g=b;this.Xd=function(a){this.cb=a;for(var b in U)if(U[b]=== +a){this.code=b;break}};this.Xd(a);this.message=ab[a]},B.e.prototype=Error(),[U.Q].forEach(function(a){B.Db[a]=new B.e(a);B.Db[a].stack=""}))},Zd:function(){B.jc();B.T=Array(4096);B.F(Y,{},"/");B.fd();B.ed()},Ga:function(a,b,c){w(!B.Ga.hb,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");B.Ga.hb=i;B.jc();p.stdin=a||p.stdin;p.stdout=b||p.stdout;p.stderr= +c||p.stderr;B.od()},Qd:function(){B.Ga.hb=m;for(var a=0;athis.length-1||0>a)){var b=a%this.cd;return this.yd(a/ +this.cd|0)[b]}};h.prototype.Wd=function(a){this.yd=a};h.prototype.bc=function(){var a=new XMLHttpRequest;a.open("HEAD",c,m);a.send(k);200<=a.status&&300>a.status||304===a.status||d(Error("Couldn't load "+c+". Status: "+a.status));var b=Number(a.getResponseHeader("Content-length")),e,f=1048576;if(!((e=a.getResponseHeader("Accept-Ranges"))&&"bytes"===e))f=b;var h=this;h.Wd(function(a){var e=a*f,j=(a+1)*f-1,j=Math.min(j,b-1);if("undefined"===typeof h.Za[a]){var l=h.Za;e>j&&d(Error("invalid range ("+ +e+", "+j+") or no bytes requested!"));j>b-1&&d(Error("only "+b+" bytes available! programmer error!"));var q=new XMLHttpRequest;q.open("GET",c,m);b!==f&&q.setRequestHeader("Range","bytes="+e+"-"+j);"undefined"!=typeof Uint8Array&&(q.responseType="arraybuffer");q.overrideMimeType&&q.overrideMimeType("text/plain; charset=x-user-defined");q.send(k);200<=q.status&&300>q.status||304===q.status||d(Error("Couldn't load "+c+". Status: "+q.status));e=q.response!==g?new Uint8Array(q.response||[]):Va(q.responseText|| +"",i);l[a]=e}"undefined"===typeof h.Za[a]&&d(Error("doXHR failed!"));return h.Za[a]});this.Uc=b;this.Tc=f;this.Hb=i};if("undefined"!==typeof XMLHttpRequest){ca||d("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc");var j=new h;Object.defineProperty(j,"length",{get:function(){this.Hb||this.bc();return this.Uc}});Object.defineProperty(j,"chunkSize",{get:function(){this.Hb||this.bc();return this.Tc}});j={Gb:m,k:j}}else j={Gb:m,url:c}; +var l=B.gd(a,b,j,e,f);j.k?l.k=j.k:j.url&&(l.k=k,l.url=j.url);Object.defineProperty(l,"usedBytes",{get:function(){return this.k.length}});var u={};Object.keys(l.p).forEach(function(a){var b=l.p[a];u[a]=function(){B.mc(l)||d(new B.e(U.ha));return b.apply(k,arguments)}});u.M=function(a,b,c,e,f){B.mc(l)||d(new B.e(U.ha));a=a.g.k;if(f>=a.length)return 0;e=Math.min(a.length-f,e);w(0<=e);if(a.slice)for(var h=0;h>h-6&63,h=h-6,c=c+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[q]}2==h?(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&3)<<4],c+="=="):4==h&&(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&15)<<2],c+="="); +s.src="data:audio/x-"+b.substr(-3)+";base64,"+c;f(s)}};s.src=l;p.noExitRuntime=i;setTimeout(function(){H||f(s)},1E4)}else return h()}});var v=p.canvas;v&&(v.Pb=v.requestPointerLock||v.mozRequestPointerLock||v.webkitRequestPointerLock||v.msRequestPointerLock||n(),v.kc=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock||document.msExitPointerLock||n(),v.kc=v.kc.bind(document),document.addEventListener("pointerlockchange",q,m),document.addEventListener("mozpointerlockchange", +q,m),document.addEventListener("webkitpointerlockchange",q,m),document.addEventListener("mspointerlockchange",q,m),p.elementPointerLock&&v.addEventListener("click",function(a){!rb&&v.Pb&&(v.Pb(),a.preventDefault())},m))}var G=b?gb(X(a,b)):a;Ya();"string"==typeof c?yb(c,function(a){x(a)},j):x(c)},indexedDB:function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},Ub:function(){return"EM_FS_"+window.location.pathname},Vb:20,Ba:"FILE_DATA",Og:function(a,b,c){var b= +b||n(),c=c||n(),e=B.indexedDB();try{var f=e.open(B.Ub(),B.Vb)}catch(h){return c(h)}f.Ld=function(){console.log("creating db");f.result.createObjectStore(B.Ba)};f.onsuccess=function(){var e=f.result.transaction([B.Ba],"readwrite"),h=e.objectStore(B.Ba),u=0,q=0,x=a.length;a.forEach(function(a){a=h.put(B.vb(a).object.k,a);a.onsuccess=function(){u++;u+q==x&&(0==q?b():c())};a.onerror=function(){q++;u+q==x&&(0==q?b():c())}});e.onerror=c};f.onerror=c},Dg:function(a,b,c){var b=b||n(),c=c||n(),e=B.indexedDB(); +try{var f=e.open(B.Ub(),B.Vb)}catch(h){return c(h)}f.Ld=c;f.onsuccess=function(){var e=f.result;try{var h=e.transaction([B.Ba],"readonly")}catch(u){c(u);return}var q=h.objectStore(B.Ba),x=0,s=0,v=a.length;a.forEach(function(a){var e=q.get(a);e.onsuccess=function(){B.vb(a).Ab&&B.za(a);B.xb(eb(a),W(a),e.result,i,i,i);x++;x+s==v&&(0==s?b():c())};e.onerror=function(){s++;x+s==v&&(0==s?b():c())}});h.onerror=c};f.onerror=c}};function zb(){d("TODO")} +var Z={F:function(){p.websocket=p.websocket&&"object"===typeof p.websocket?p.websocket:{};p.websocket.tb={};p.websocket.on=function(a,b){"function"===typeof b&&(this.tb[a]=b);return this};p.websocket.P=function(a,b){"function"===typeof this.tb[a]&&this.tb[a].call(this,b)};return B.createNode(k,"/",16895,0)},nd:function(a,b,c){c&&w(1==b==(6==c));a={qd:a,type:b,protocol:c,G:k,error:k,Ma:{},Kb:[],ua:[],wa:Z.L};b=Z.mb();c=B.createNode(Z.root,b,49152,0);c.va=a;b=B.fc({path:b,g:c,D:B.wc("r+"),seekable:m, +p:Z.p});a.A=b;return a},wd:function(a){a=B.qa(a);return!a||!B.Ed(a.g.mode)?k:a.g.va},p:{zc:function(a){a=a.g.va;return a.wa.zc(a)},Ha:function(a,b,c){a=a.g.va;return a.wa.Ha(a,b,c)},M:function(a,b,c,e){a=a.g.va;e=a.wa.Rd(a,e);if(!e)return 0;b.set(e.buffer,c);return e.buffer.length},write:function(a,b,c,e){a=a.g.va;return a.wa.Vd(a,b,c,e)},close:function(a){a=a.g.va;a.wa.close(a)}},mb:function(){Z.mb.gc||(Z.mb.gc=0);return"socket["+Z.mb.gc++ +"]"},L:{$a:function(a,b,c){var e;"object"===typeof b&&(e= +b,c=b=k);if(e)e._socket?(b=e._socket.remoteAddress,c=e._socket.remotePort):((c=/ws[s]?:\/\/([^:]+):(\d+)/.exec(e.url))||d(Error("WebSocket URL must be in the format ws(s)://address:port")),b=c[1],c=parseInt(c[2],10));else try{var f=p.websocket&&"object"===typeof p.websocket,h="ws:#".replace("#","//");f&&"string"===typeof p.websocket.url&&(h=p.websocket.url);if("ws://"===h||"wss://"===h)var j=b.split("/"),h=h+j[0]+":"+c+"/"+j.slice(1).join("/");j="binary";f&&"string"===typeof p.websocket.subprotocol&& +(j=p.websocket.subprotocol);var j=j.replace(/^ +| +$/g,"").split(/ *, */),l=t?{protocol:j.toString()}:j;e=new (t?(null)("ws"):window.WebSocket)(h,l);e.binaryType="arraybuffer"}catch(u){d(new B.e(U.Yb))}b={W:b,port:c,o:e,ab:[]};Z.L.$b(a,b);Z.L.zd(a,b);2===a.type&&"undefined"!==typeof a.ya&&b.ab.push(new Uint8Array([255,255,255,255,112,111,114,116,(a.ya&65280)>>8,a.ya&255]));return b},gb:function(a,b,c){return a.Ma[b+":"+c]},$b:function(a,b){a.Ma[b.W+":"+b.port]=b},Bc:function(a,b){delete a.Ma[b.W+ +":"+b.port]},zd:function(a,b){function c(){p.websocket.P("open",a.A.C);try{for(var c=b.ab.shift();c;)b.o.send(c),c=b.ab.shift()}catch(e){b.o.close()}}function e(c){w("string"!==typeof c&&c.byteLength!==g);var c=new Uint8Array(c),e=f;f=m;e&&10===c.length&&255===c[0]&&255===c[1]&&255===c[2]&&255===c[3]&&112===c[4]&&111===c[5]&&114===c[6]&&116===c[7]?(c=c[8]<<8|c[9],Z.L.Bc(a,b),b.port=c,Z.L.$b(a,b)):(a.ua.push({W:b.W,port:b.port,data:c}),p.websocket.P("message",a.A.C))}var f=i;t?(b.o.on("open",c),b.o.on("message", +function(a,b){b.binary&&e((new Uint8Array(a)).buffer)}),b.o.on("close",function(){p.websocket.P("close",a.A.C)}),b.o.on("error",function(){a.error=U.Wb;p.websocket.P("error",[a.A.C,a.error,"ECONNREFUSED: Connection refused"])})):(b.o.onopen=c,b.o.onclose=function(){p.websocket.P("close",a.A.C)},b.o.onmessage=function(a){e(a.data)},b.o.onerror=function(){a.error=U.Wb;p.websocket.P("error",[a.A.C,a.error,"ECONNREFUSED: Connection refused"])})},zc:function(a){if(1===a.type&&a.G)return a.Kb.length?65: +0;var b=0,c=1===a.type?Z.L.gb(a,a.Y,a.Z):k;if(a.ua.length||!c||c&&c.o.readyState===c.o.Pa||c&&c.o.readyState===c.o.CLOSED)b|=65;if(!c||c&&c.o.readyState===c.o.OPEN)b|=4;if(c&&c.o.readyState===c.o.Pa||c&&c.o.readyState===c.o.CLOSED)b|=16;return b},Ha:function(a,b,c){switch(b){case 21531:return b=0,a.ua.length&&(b=a.ua[0].data.length),K[c>>2]=b,0;default:return U.B}},close:function(a){if(a.G){try{a.G.close()}catch(b){}a.G=k}for(var c=Object.keys(a.Ma),e=0;e>0]=c;if(-1==Ab(Cb(b),Eb.Cc,1)){if(c=B.pc(b))c.error=i;return-1}return c}function Fb(a){Fb.$c||(E=E+4095&-4096,Fb.$c=i,w(z.bb),Fb.Wc=z.bb,z.bb=function(){A("cannot dynamically allocate, sbrk now has control")});var b=E;0!=a&&Fb.Wc(a);return b}p._memset=Gb;function Hb(a,b,c){window._broadwayOnPictureDecoded(a,b,c)}p._broadwayOnPictureDecoded=Hb;function Ib(){window._broadwayOnHeadersDecoded()}p._broadwayOnHeadersDecoded=Ib; +function Jb(a,b){Kb=a;Lb=b;if(!Mb)return 1;0==a?(Nb=function(){setTimeout(Ob,b)},Pb="timeout"):1==a&&(Nb=function(){Qb(Ob)},Pb="rAF");return 0} +function Rb(a,b,c,e){p.noExitRuntime=i;w(!Mb,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");Mb=a;Sb=e;var f=Tb;Ob=function(){if(!H)if(0=bc;)bc+=1E3/60;b=Math.max(bc-b,0);setTimeout(a,b)}function Qb(a){"undefined"===typeof window?cc(a):(window.requestAnimationFrame||(window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||cc),window.requestAnimationFrame(a))} +function xb(a){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",bmp:"image/bmp",ogg:"audio/ogg",wav:"audio/wav",mp3:"audio/mpeg"}[a.substr(a.lastIndexOf(".")+1)]} +function yb(a,b,c){function e(){c?c():d('Loading data file "'+a+'" failed.')}var f=new XMLHttpRequest;f.open("GET",a,i);f.responseType="arraybuffer";f.onload=function(){if(200==f.status||0==f.status&&f.response){var c=f.response;w(c,'Loading data file "'+a+'" failed (no arrayBuffer).');b(new Uint8Array(c));Za()}else e()};f.onerror=e;f.send(k);Ya()}var dc=[];function ec(){var a=p.canvas;dc.forEach(function(b){b(a.width,a.height)})} +function fc(a,b,c){b&&c?(a.ae=b,a.Ad=c):(b=a.ae,c=a.Ad);var e=b,f=c;p.forcedAspectRatio&&0>2]=0;R.unshift({ja:n()});Qa.push({ja:n()});var lb=new z.Da;t&&((null)("fs"),process.platform.match(/^win/));R.push({ja:function(){Z.root=B.F(Z,{},k)}}); +Eb.Cc=M([0],"i8",L); +p.requestFullScreen=function(a,b){function c(){Yb=m;var a=e.parentNode;(document.webkitFullScreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.mozFullscreenElement||document.fullScreenElement||document.fullscreenElement||document.msFullScreenElement||document.msFullscreenElement||document.webkitCurrentFullScreenElement)===a?(e.cc=document.cancelFullScreen||document.mozCancelFullScreen||document.webkitCancelFullScreen||document.msExitFullscreen||document.exitFullscreen|| +n(),e.cc=e.cc.bind(document),$b&&e.Pb(),Yb=i,ac&&("undefined"!=typeof SDL&&(a=Ha[SDL.screen+0*z.ia>>2],K[SDL.screen+0*z.ia>>2]=a|8388608),ec())):(a.parentNode.insertBefore(e,a),a.parentNode.removeChild(a),ac&&("undefined"!=typeof SDL&&(a=Ha[SDL.screen+0*z.ia>>2],K[SDL.screen+0*z.ia>>2]=a&-8388609),ec()));if(p.onFullScreen)p.onFullScreen(Yb);fc(e)}$b=a;ac=b;"undefined"===typeof $b&&($b=i);"undefined"===typeof ac&&(ac=m);var e=p.canvas;Zb||(Zb=i,document.addEventListener("fullscreenchange",c,m),document.addEventListener("mozfullscreenchange", +c,m),document.addEventListener("webkitfullscreenchange",c,m),document.addEventListener("MSFullscreenChange",c,m));var f=document.createElement("div");e.parentNode.insertBefore(f,e);f.appendChild(e);f.Td=f.requestFullScreen||f.mozRequestFullScreen||f.msRequestFullscreen||(f.webkitRequestFullScreen?function(){f.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}:k);f.Td()};p.requestAnimationFrame=function(a){Qb(a)};p.setCanvasSize=function(a,b,c){fc(p.canvas,a,b);c||ec()}; +p.pauseMainLoop=function(){Nb=k;Tb++};p.resumeMainLoop=function(){Tb++;var a=Kb,b=Lb,c=Mb;Mb=k;Rb(c,0,m,Sb);Jb(a,b)};p.getUserMedia=function(){window.qc||(window.qc=navigator.getUserMedia||navigator.mozGetUserMedia);window.qc(g)};Ja=y=z.ub(D);Ka=Ja+Ma;La=E=z.ub(Ka);w(La>2],a=Db(a,b);return 0>a?a:0>Eb(10,b)?-1:a+1},_fflush:n(),_fputc:Eb,_send:function(a,b,c){return!Z.wd(a)?(V(U.V),-1):Ab(a,b,c)},_pwrite:function(a,b,c,e){a=B.qa(a);if(!a)return V(U.V),-1;try{return B.write(a,I,b,c,e)}catch(f){return B.sc(f),-1}},_fputs:Db,_emscripten_set_main_loop:Rb, +_abort:function(){p.abort()},___setErrNo:V,_sbrk:Fb,_mkport:zb,_emscripten_set_main_loop_timing:Jb,_emscripten_memcpy_big:function(a,b,c){N.set(N.subarray(b,b+c),a);return a},_fileno:Cb,_broadwayOnHeadersDecoded:Ib,_write:Ab,_time:function(a){var b=Date.now()/1E3|0;a&&(K[a>>2]=b);return b},_sysconf:function(a){switch(a){case 30:return 4096;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 79:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809; +case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32; +case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1E3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:return"object"===typeof navigator?navigator.hardwareConcurrency||1:1}V(U.B);return-1}, +___errno_location:function(){return bb},STACKTOP:y,STACK_MAX:Ka,tempDoublePtr:$a,ABORT:H,NaN:NaN,Infinity:Infinity};// EMSCRIPTEN_START_ASM +var $=(function(global,env,buffer) { +"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=0;var n=0;var o=0;var p=0;var q=+env.NaN,r=+env.Infinity;var s=0,t=0,u=0,v=0,w=0.0,x=0,y=0,z=0,A=0.0;var B=0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=global.Math.floor;var M=global.Math.abs;var N=global.Math.sqrt;var O=global.Math.pow;var P=global.Math.cos;var Q=global.Math.sin;var R=global.Math.tan;var S=global.Math.acos;var T=global.Math.asin;var U=global.Math.atan;var V=global.Math.atan2;var W=global.Math.exp;var X=global.Math.log;var Y=global.Math.ceil;var Z=global.Math.imul;var _=env.abort;var $=env.assert;var aa=env.min;var ba=env.invoke_viiiii;var ca=env._broadwayOnPictureDecoded;var da=env._puts;var ea=env._fflush;var fa=env._fputc;var ga=env._send;var ha=env._pwrite;var ia=env._fputs;var ja=env._emscripten_set_main_loop;var ka=env._abort;var la=env.___setErrNo;var ma=env._sbrk;var na=env._mkport;var oa=env._emscripten_set_main_loop_timing;var pa=env._emscripten_memcpy_big;var qa=env._fileno;var ra=env._broadwayOnHeadersDecoded;var sa=env._write;var ta=env._time;var ua=env._sysconf;var va=env.___errno_location;var wa=0.0; +// EMSCRIPTEN_START_FUNCS +function Sb(a,f,g,h,j,k){a=a|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0;X=i;i=i+32|0;W=X;p=c[j+4>>2]|0;V=(h>>>0)/(p>>>0)|0;U=V<<4;V=h-(Z(V,p)|0)<<4;c[W+4>>2]=p;c[W+8>>2]=c[j+8>>2];p=c[a>>2]|0;do if((p|0)==1|(p|0)==0){A=c[f+144>>2]|0;l=a+4|0;n=c[a+200>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){o=n+152|0;o=e[o>>1]|e[o+2>>1]<<16;m=1;v=o&65535;o=o>>>16&65535;s=c[n+104>>2]|0}else{m=1;v=0;o=0;s=-1}else{m=0;v=0;o=0;s=-1}n=c[a+204>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){w=n+172|0;w=e[w>>1]|e[w+2>>1]<<16;u=w&65535;q=1;r=c[n+108>>2]|0;w=w>>>16&65535}else{u=0;q=1;r=-1;w=0}else{u=0;q=0;r=-1;w=0}do if(!p)if(!((m|0)==0|(q|0)==0)){if((s|0)==0?((o&65535)<<16|v&65535|0)==0:0){n=0;o=0;break}if((r|0)==0?((w&65535)<<16|u&65535|0)==0:0){n=0;o=0}else T=16}else{n=0;o=0}else T=16;while(0);if((T|0)==16){y=b[f+160>>1]|0;z=b[f+162>>1]|0;n=c[a+208>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){t=n+172|0;p=c[n+108>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;T=25}else{p=-1;t=0;T=25}else T=20;do if((T|0)==20){p=c[a+212>>2]|0;if((p|0)!=0?(c[p+4>>2]|0)==(c[l>>2]|0):0){if((c[p>>2]|0)>>>0>=6){p=-1;t=0;T=25;break}t=p+192|0;p=c[p+112>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;T=25;break}if((m|0)==0|(q|0)!=0){p=-1;t=0;T=25}else n=v}while(0);do if((T|0)==25){m=(s|0)==(A|0);n=(r|0)==(A|0);if(((n&1)+(m&1)+((p|0)==(A|0)&1)|0)==1){if(m|n){n=m?v:u;o=m?o:w;break}n=t&65535;o=t>>>16&65535;break}n=v<<16>>16;l=u<<16>>16;p=t<<16>>16;if(u<<16>>16>v<<16>>16)m=l;else{m=n;n=(l|0)<(n|0)?l:n}if((m|0)<(p|0))p=m;else p=(n|0)>(p|0)?n:p;n=o<<16>>16;m=w<<16>>16;l=t>>16;if(w<<16>>16>o<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=p&65535;o=o&65535}while(0);n=(n&65535)+(y&65535)|0;o=(o&65535)+(z&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}else{n=n&65535;o=o&65535}}l=ic(g,A)|0;if(!l){G=1;i=X;return G|0}else{G=a+132|0;E=a+136|0;D=a+140|0;C=a+144|0;B=a+148|0;z=a+152|0;y=a+156|0;x=a+160|0;w=a+164|0;v=a+168|0;m=a+172|0;p=a+176|0;q=a+180|0;r=a+184|0;s=a+188|0;F=a+192|0;b[a+192>>1]=n;b[a+194>>1]=o;F=e[F>>1]|e[F+2>>1]<<16;b[s>>1]=F;b[s+2>>1]=F>>>16;b[r>>1]=F;b[r+2>>1]=F>>>16;b[q>>1]=F;b[q+2>>1]=F>>>16;b[p>>1]=F;b[p+2>>1]=F>>>16;b[m>>1]=F;b[m+2>>1]=F>>>16;b[v>>1]=F;b[v+2>>1]=F>>>16;b[w>>1]=F;b[w+2>>1]=F>>>16;b[x>>1]=F;b[x+2>>1]=F>>>16;b[y>>1]=F;b[y+2>>1]=F>>>16;b[z>>1]=F;b[z+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+100>>2]=A;c[a+104>>2]=A;c[a+108>>2]=A;c[a+112>>2]=A;c[a+116>>2]=l;c[a+120>>2]=l;c[a+124>>2]=l;c[a+128>>2]=l;c[W>>2]=l;dc(k,a+132|0,W,V,U,0,0,16,16);break}}else if((p|0)==3){x=b[f+160>>1]|0;y=b[f+162>>1]|0;C=c[f+144>>2]|0;u=a+4|0;o=c[a+200>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){w=o+152|0;w=e[w>>1]|e[w+2>>1]<<16;n=1;s=w&65535;w=w>>>16&65535;o=c[o+104>>2]|0}else{n=1;s=0;w=0;o=-1}else{n=0;s=0;w=0;o=-1}a:do if((o|0)==(C|0)){n=s;o=w}else{o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){G=o+172|0;G=e[G>>1]|e[G+2>>1]<<16;t=o+188|0;p=c[o+108>>2]|0;l=c[o+112>>2]|0;n=G&65535;o=G>>>16&65535;t=e[t>>1]|e[t+2>>1]<<16}else{p=-1;l=-1;n=0;o=0;t=0}else T=107;do if((T|0)==107){o=c[a+212>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0){if((c[o>>2]|0)>>>0>=6){p=-1;l=-1;n=0;o=0;t=0;break}t=o+192|0;p=-1;l=c[o+112>>2]|0;n=0;o=0;t=e[t>>1]|e[t+2>>1]<<16;break}if(!n){p=-1;l=-1;n=0;o=0;t=0}else{n=s;o=w;break a}}while(0);m=(p|0)==(C|0);if(((m&1)+((l|0)==(C|0)&1)|0)==1){if(m)break;n=t&65535;o=t>>>16&65535;break}l=s<<16>>16;p=n<<16>>16;q=t<<16>>16;if(n<<16>>16>s<<16>>16){m=p;n=l}else{m=l;n=(p|0)<(l|0)?p:l}if((m|0)<(q|0))q=m;else q=(n|0)>(q|0)?n:q;n=w<<16>>16;m=o<<16>>16;l=t>>16;if(o<<16>>16>w<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=q&65535;o=o&65535}while(0);n=(n&65535)+(x&65535)|0;o=(o&65535)+(y&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}m=ic(g,C)|0;if(!m){G=1;i=X;return G|0}x=a+132|0;z=a+136|0;A=a+140|0;y=a+144|0;G=a+164|0;F=a+168|0;E=a+172|0;w=a+176|0;b[a+176>>1]=n;b[a+178>>1]=o;w=e[w>>1]|e[w+2>>1]<<16;b[E>>1]=w;b[E+2>>1]=w>>>16;b[F>>1]=w;b[F+2>>1]=w>>>16;b[G>>1]=w;b[G+2>>1]=w>>>16;b[y>>1]=w;b[y+2>>1]=w>>>16;b[A>>1]=w;b[A+2>>1]=w>>>16;b[z>>1]=w;b[z+2>>1]=w>>>16;b[x>>1]=w;b[x+2>>1]=w>>>16;c[a+100>>2]=C;c[a+108>>2]=C;x=a+116|0;c[x>>2]=m;c[a+124>>2]=m;z=b[f+164>>1]|0;A=b[f+166>>1]|0;y=c[f+148>>2]|0;o=c[a+208>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){r=o+172|0;o=c[o+108>>2]|0;p=1;r=e[r>>1]|e[r+2>>1]<<16}else{o=-1;p=1;r=0}else{o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){r=o+176|0;o=c[o+108>>2]|0;p=1;r=e[r>>1]|e[r+2>>1]<<16}else{o=-1;p=1;r=0}else{o=-1;p=0;r=0}}do if((o|0)!=(y|0)){s=w&65535;o=w>>>16;v=o&65535;n=c[a+204>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[u>>2]|0):0)if((c[n>>2]|0)>>>0<6){u=n+188|0;u=e[u>>1]|e[u+2>>1]<<16;p=c[n+112>>2]|0;l=u&65535;u=u>>>16&65535}else{p=-1;l=0;u=0}else if(!p){m=w;break}else{p=-1;l=0;u=0}m=(C|0)==(y|0);n=(p|0)==(y|0);if(((n&1)+(m&1)|0)==1){if(m){m=w;break}if(n){o=u&65535;m=o<<16|l&65535;break}else{m=r;o=r>>>16;break}}o=w<<16>>16;p=l<<16>>16;q=r<<16>>16;if(l<<16>>16>s<<16>>16)m=p;else{m=o;o=(p|0)<(o|0)?p:o}if((m|0)>=(q|0))m=(o|0)>(q|0)?o:q;n=w>>16;l=u<<16>>16;p=r>>16;if(u<<16>>16>v<<16>>16)o=l;else{o=n;n=(l|0)<(n|0)?l:n}if((o|0)>=(p|0))o=(n|0)>(p|0)?n:p}else{m=r;o=r>>>16}while(0);m=(m&65535)+(z&65535)|0;n=(o&65535)+(A&65535)|0;if(((m<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((n<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}o=ic(g,y)|0;if(!o){G=1;i=X;return G|0}else{G=a+148|0;E=a+152|0;D=a+156|0;C=a+160|0;B=a+180|0;A=a+184|0;z=a+188|0;F=a+192|0;b[a+192>>1]=m;b[a+194>>1]=n;F=e[F>>1]|e[F+2>>1]<<16;b[z>>1]=F;b[z+2>>1]=F>>>16;b[A>>1]=F;b[A+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+104>>2]=y;c[a+112>>2]=y;F=a+120|0;c[F>>2]=o;c[a+128>>2]=o;c[W>>2]=c[x>>2];dc(k,a+132|0,W,V,U,0,0,8,16);c[W>>2]=c[F>>2];dc(k,G,W,V,U,8,0,8,16);break}}else if((p|0)==2){z=b[f+160>>1]|0;A=b[f+162>>1]|0;C=c[f+144>>2]|0;B=a+4|0;o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[B>>2]|0):0)if((c[o>>2]|0)>>>0<6){w=o+172|0;w=e[w>>1]|e[w+2>>1]<<16;m=1;o=c[o+108>>2]|0;r=w&65535;w=w>>>16&65535}else{m=1;o=-1;r=0;w=0}else{m=0;o=-1;r=0;w=0}b:do if((o|0)==(C|0)){n=r;o=w}else{n=c[a+200>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0)if((c[n>>2]|0)>>>0<6){o=n+152|0;o=e[o>>1]|e[o+2>>1]<<16;q=1;s=o&65535;o=o>>>16&65535;p=c[n+104>>2]|0}else{q=1;s=0;o=0;p=-1}else{q=0;s=0;o=0;p=-1}n=c[a+208>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0)if((c[n>>2]|0)>>>0<6){t=n+172|0;n=c[n+108>>2]|0;t=e[t>>1]|e[t+2>>1]<<16}else{n=-1;t=0}else T=54;do if((T|0)==54){n=c[a+212>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0){if((c[n>>2]|0)>>>0>=6){n=-1;t=0;break}t=n+192|0;n=c[n+112>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;break}if((q|0)==0|(m|0)!=0){n=-1;t=0}else{n=s;break b}}while(0);m=(p|0)==(C|0);if((((n|0)==(C|0)&1)+(m&1)|0)==1){if(m){n=m?s:r;o=m?o:w;break}n=t&65535;o=t>>>16&65535;break}n=s<<16>>16;l=r<<16>>16;p=t<<16>>16;if(r<<16>>16>s<<16>>16)m=l;else{m=n;n=(l|0)<(n|0)?l:n}if((m|0)<(p|0))q=m;else q=(n|0)>(p|0)?n:p;n=o<<16>>16;m=w<<16>>16;l=t>>16;if(w<<16>>16>o<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=q&65535;o=o&65535}while(0);n=(n&65535)+(z&65535)|0;o=(o&65535)+(A&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}m=ic(g,C)|0;if(!m){G=1;i=X;return G|0}A=a+132|0;x=a+136|0;y=a+140|0;z=a+144|0;q=a+148|0;p=a+152|0;G=a+156|0;v=a+160|0;b[a+160>>1]=n;b[a+162>>1]=o;v=e[v>>1]|e[v+2>>1]<<16;b[G>>1]=v;b[G+2>>1]=v>>>16;b[p>>1]=v;b[p+2>>1]=v>>>16;b[q>>1]=v;b[q+2>>1]=v>>>16;b[z>>1]=v;b[z+2>>1]=v>>>16;b[y>>1]=v;b[y+2>>1]=v>>>16;b[x>>1]=v;b[x+2>>1]=v>>>16;b[A>>1]=v;b[A+2>>1]=v>>>16;c[a+100>>2]=C;c[a+104>>2]=C;A=a+116|0;c[A>>2]=m;c[a+120>>2]=m;x=b[f+164>>1]|0;y=b[f+166>>1]|0;z=c[f+148>>2]|0;q=c[a+200>>2]|0;p=(q|0)==0;if((!p?(c[q+4>>2]|0)==(c[B>>2]|0):0)?(c[q>>2]|0)>>>0<6:0){w=q+184|0;w=e[w>>1]|e[w+2>>1]<<16;r=w&65535;w=w>>>16&65535;o=c[q+112>>2]|0}else{r=0;w=0;o=-1}do if((o|0)!=(z|0)){s=v&65535;n=v>>>16;u=n&65535;if((!p?(c[q+4>>2]|0)==(c[B>>2]|0):0)?(c[q>>2]|0)>>>0<6:0){t=q+160|0;p=c[q+104>>2]|0;t=e[t>>1]|e[t+2>>1]<<16}else{p=-1;t=0}o=(C|0)==(z|0);if((((p|0)==(z|0)&1)+(o&1)|0)==1){m=o?v:t;o=o?n:t>>>16;break}o=r<<16>>16;p=v<<16>>16;q=t<<16>>16;if(s<<16>>16>r<<16>>16)m=p;else{m=o;o=(p|0)<(o|0)?p:o}if((m|0)>=(q|0))m=(o|0)>(q|0)?o:q;n=w<<16>>16;l=v>>16;p=t>>16;if(u<<16>>16>w<<16>>16)o=l;else{o=n;n=(l|0)<(n|0)?l:n}if((o|0)>=(p|0))o=(n|0)>(p|0)?n:p}else{o=w&65535;m=o<<16|r&65535}while(0);m=(m&65535)+(x&65535)|0;n=(o&65535)+(y&65535)|0;if(((m<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((n<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}o=ic(g,z)|0;if(!o){G=1;i=X;return G|0}else{G=a+164|0;E=a+168|0;D=a+172|0;C=a+176|0;B=a+180|0;y=a+184|0;x=a+188|0;F=a+192|0;b[a+192>>1]=m;b[a+194>>1]=n;F=e[F>>1]|e[F+2>>1]<<16;b[x>>1]=F;b[x+2>>1]=F>>>16;b[y>>1]=F;b[y+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+108>>2]=z;c[a+112>>2]=z;F=a+124|0;c[F>>2]=o;c[a+128>>2]=o;c[W>>2]=c[A>>2];dc(k,a+132|0,W,V,U,0,0,16,8);c[W>>2]=c[F>>2];dc(k,G,W,V,U,0,8,16,8);break}}else{S=a+4|0;H=0;c:while(1){D=f+(H<<2)+176|0;G=eb(c[D>>2]|0)|0;E=f+(H<<2)+192|0;c[a+(H<<2)+100>>2]=c[E>>2];F=ic(g,c[E>>2]|0)|0;c[a+(H<<2)+116>>2]=F;if(!F){l=1;T=212;break}if(G){J=H<<2;K=a+(J<<2)+132|0;O=a+(J<<2)+134|0;P=J|1;L=a+(P<<2)+132|0;P=a+(P<<2)+134|0;Q=J|2;M=a+(Q<<2)+132|0;Q=a+(Q<<2)+134|0;R=J|3;N=a+(R<<2)+132|0;R=a+(R<<2)+134|0;I=0;do{C=b[f+(H<<4)+(I<<2)+208>>1]|0;B=b[f+(H<<4)+(I<<2)+210>>1]|0;F=hb(c[D>>2]|0)|0;n=c[E>>2]|0;s=ub(a,c[6288+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;r=d[6288+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((s|0)!=0?(c[s+4>>2]|0)==(c[S>>2]|0):0)if((c[s>>2]|0)>>>0<6){q=s+(r<<2)+132|0;q=e[q>>1]|e[q+2>>1]<<16;A=c[s+(r>>>2<<2)+100>>2]|0;o=q&65535;z=1;q=q>>>16&65535}else{A=-1;o=0;z=1;q=0}else{A=-1;o=0;z=0;q=0}v=ub(a,c[5776+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;l=d[5776+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((v|0)!=0?(c[v+4>>2]|0)==(c[S>>2]|0):0)if((c[v>>2]|0)>>>0<6){p=v+(l<<2)+132|0;p=e[p>>1]|e[p+2>>1]<<16;y=1;x=c[v+(l>>>2<<2)+100>>2]|0;m=p&65535;p=p>>>16&65535}else{y=1;x=-1;m=0;p=0}else{y=0;x=-1;m=0;p=0}w=ub(a,c[5264+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;v=d[5264+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((w|0)!=0?(c[w+4>>2]|0)==(c[S>>2]|0):0)if((c[w>>2]|0)>>>0<6){z=w+(v<<2)+132|0;z=e[z>>1]|e[z+2>>1]<<16;v=c[w+(v>>>2<<2)+100>>2]|0;T=180}else{z=0;v=-1;T=180}else T=175;do if((T|0)==175){T=0;w=ub(a,c[4752+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;v=d[4752+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((w|0)!=0?(c[w+4>>2]|0)==(c[S>>2]|0):0){if((c[w>>2]|0)>>>0>=6){z=0;v=-1;T=180;break}z=w+(v<<2)+132|0;z=e[z>>1]|e[z+2>>1]<<16;v=c[w+(v>>>2<<2)+100>>2]|0;T=180;break}if((z|0)==0|(y|0)!=0){z=0;v=-1;T=180}else{v=o;t=q}}while(0);do if((T|0)==180){l=(A|0)==(n|0);w=(x|0)==(n|0);if(((w&1)+(l&1)+((v|0)==(n|0)&1)|0)==1){if(l|w){v=l?o:m;t=l?q:p;break}v=z&65535;t=z>>>16&65535;break}u=o<<16>>16;w=m<<16>>16;l=z<<16>>16;if(m<<16>>16>o<<16>>16)v=w;else{v=u;u=(w|0)<(u|0)?w:u}if((v|0)<(l|0))w=v;else w=(u|0)>(l|0)?u:l;t=q<<16>>16;v=p<<16>>16;l=z>>16;if(p<<16>>16>q<<16>>16)s=v;else{s=t;t=(v|0)<(t|0)?v:t}if((s|0)>=(l|0))s=(t|0)>(l|0)?t:l;v=w&65535;t=s&65535}while(0);C=(v&65535)+(C&65535)|0;q=C&65535;s=(t&65535)+(B&65535)|0;r=s&65535;if(((C<<16>>16)+8192|0)>>>0>16383){l=1;T=212;break c}if(((s<<16>>16)+2048|0)>>>0>4095){l=1;T=212;break c}if(!F){b[K>>1]=q;b[O>>1]=r;b[L>>1]=q;b[P>>1]=r;b[M>>1]=q;b[Q>>1]=r;b[N>>1]=q;b[R>>1]=r}else if((F|0)==1){F=(I<<1)+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r;F=F|1;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}else if((F|0)==2){F=I+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r;F=F+2|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}else if((F|0)==3){F=I+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}I=I+1|0}while(I>>>0>>0)}H=H+1|0;if(H>>>0>=4){T=201;break}}if((T|0)==201){o=0;do{c[W>>2]=c[a+(o<<2)+116>>2];m=hb(c[f+(o<<2)+176>>2]|0)|0;l=o<<3&8;n=o>>>0<2?0:8;if(!m)dc(k,a+(o<<2<<2)+132|0,W,V,U,l,n,8,8);else if((m|0)==1){G=o<<2;dc(k,a+(G<<2)+132|0,W,V,U,l,n,8,4);dc(k,a+((G|2)<<2)+132|0,W,V,U,l,n|4,8,4)}else if((m|0)==2){G=o<<2;dc(k,a+(G<<2)+132|0,W,V,U,l,n,4,8);dc(k,a+((G|1)<<2)+132|0,W,V,U,l|4,n,4,8)}else{E=o<<2;dc(k,a+(E<<2)+132|0,W,V,U,l,n,4,4);F=l|4;dc(k,a+((E|1)<<2)+132|0,W,V,U,F,n,4,4);G=n|4;dc(k,a+((E|2)<<2)+132|0,W,V,U,l,G,4,4);dc(k,a+((E|3)<<2)+132|0,W,V,U,F,G,4,4)}o=o+1|0}while((o|0)!=4)}else if((T|0)==212){i=X;return l|0}}while(0);if((c[a+196>>2]|0)>>>0>1){G=0;i=X;return G|0}if(!(c[a>>2]|0)){sc(j,k);G=0;i=X;return G|0}else{tc(j,h,k,f+328|0);G=0;i=X;return G|0}return 0}function Tb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;B=i;i=i+144|0;m=B;if((e|0)>=0?!((e+1+k|0)>>>0>g>>>0|(f|0)<0|(l+f|0)>>>0>h>>>0):0)m=b;else{A=k+1|0;Ub(b,m,e,f,g,h,A,l,A);Ub(b+(Z(h,g)|0)|0,m+(Z(A,l)|0)|0,e,f,g,h,A,l,A);h=l;g=A;e=0;f=0}A=8-j|0;v=l>>>1;z=(v|0)==0;w=k>>>1;y=(w|0)==0;x=16-k|0;u=(g<<1)-k|0;s=g+1|0;t=g+2|0;p=w<<1;r=0;do{l=m+((Z((Z(r,h)|0)+f|0,g)|0)+e)|0;if(!(z|y)){q=c+(r<<6)|0;o=v;while(1){k=q;b=l;n=w;while(1){D=d[b>>0]|0;E=d[b+s>>0]|0;F=b;b=b+2|0;C=d[F+1>>0]|0;a[k+8>>0]=(((Z(E,j)|0)+(Z(d[F+g>>0]|0,A)|0)<<3)+32|0)>>>6;a[k>>0]=(((Z(C,j)|0)+(Z(D,A)|0)<<3)+32|0)>>>6;D=d[b>>0]|0;a[k+9>>0]=(((Z(d[F+t>>0]|0,j)|0)+(Z(E,A)|0)<<3)+32|0)>>>6;a[k+1>>0]=(((Z(D,j)|0)+(Z(C,A)|0)<<3)+32|0)>>>6;n=n+-1|0;if(!n)break;else k=k+2|0}o=o+-1|0;if(!o)break;else{q=q+(p+x)|0;l=l+(p+u)|0}}}r=r+1|0}while((r|0)!=2);i=B;return}function Ub(a,b,c,d,e,f,g,h,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;k=g+c|0;o=h+d|0;s=(c|0)<0|(k|0)>(e|0)?2:1;m=(o|0)<0?0-h|0:d;d=(k|0)<0?0-g|0:c;m=(m|0)>(f|0)?f:m;d=(d|0)>(e|0)?e:d;k=d+g|0;l=m+h|0;if((d|0)>0)a=a+d|0;if((m|0)>0)a=a+(Z(m,e)|0)|0;r=(d|0)<0?0-d|0:0;q=(k|0)>(e|0)?k-e|0:0;p=g-r-q|0;g=0-m|0;m=(m|0)<0?g:0;c=l-f|0;n=(l|0)>(f|0)?c:0;k=h-m|0;d=k-n|0;if(m){m=h+-1-((o|0)>0?o:0)|0;l=~f;l=(m|0)>(l|0)?m:l;m=~l;m=Z(l+((m|0)>0?m:0)+1|0,j)|0;l=b;while(1){xa[s&3](a,l,r,p,q);g=g+-1|0;if(!g)break;else l=l+j|0}b=b+m|0}if((k|0)!=(n|0)){l=h+-1|0;g=l-((o|0)>0?o:0)|0;k=~f;k=(g|0)>(k|0)?g:k;l=l-k|0;g=~k;g=h+f+-1-((l|0)<(f|0)?f:l)-k-((g|0)>0?g:0)|0;k=Z(g,j)|0;g=Z(g,e)|0;l=b;m=a;while(1){xa[s&3](m,l,r,p,q);d=d+-1|0;if(!d)break;else{l=l+j|0;m=m+e|0}}b=b+k|0;a=a+g|0}a=a+(0-e)|0;if(!n){i=t;return}while(1){xa[s&3](a,b,r,p,q);c=c+-1|0;if(!c)break;else b=b+j|0}i=t;return}function Vb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;C=i;i=i+144|0;m=C;if(((e|0)>=0?!((k+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+1+l|0)>>>0<=h>>>0:0)m=b;else{A=l+1|0;Ub(b,m,e,f,g,h,k,A,k);Ub(b+(Z(h,g)|0)|0,m+(Z(A,k)|0)|0,e,f,g,h,k,A,k);h=A;g=k;e=0;f=0}B=8-j|0;w=l>>>1;A=(w|0)==0;x=k>>>1;z=(x|0)==0;y=16-k|0;v=g<<1;u=v-k|0;t=v|1;s=g+1|0;p=x<<1;r=0;do{l=m+((Z((Z(r,h)|0)+f|0,g)|0)+e)|0;if(!(A|z)){q=c+(r<<6)|0;o=w;while(1){k=q;b=l;n=x;while(1){D=d[b+g>>0]|0;E=d[b>>0]|0;a[k+8>>0]=(((Z(D,B)|0)+(Z(d[b+v>>0]|0,j)|0)<<3)+32|0)>>>6;a[k>>0]=(((Z(E,B)|0)+(Z(D,j)|0)<<3)+32|0)>>>6;D=d[b+s>>0]|0;E=d[b+1>>0]|0;a[k+9>>0]=(((Z(D,B)|0)+(Z(d[b+t>>0]|0,j)|0)<<3)+32|0)>>>6;a[k+1>>0]=(((Z(E,B)|0)+(Z(D,j)|0)<<3)+32|0)>>>6;n=n+-1|0;if(!n)break;else{k=k+2|0;b=b+2|0}}o=o+-1|0;if(!o)break;else{q=q+(p+y)|0;l=l+(p+u)|0}}}r=r+1|0}while((r|0)!=2);i=C;return}function Wb(b,c,e,f,g,h,j,k,l,m){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;I=i;i=i+176|0;n=I;if(((e|0)>=0?!((e+1+l|0)>>>0>g>>>0|(f|0)<0):0)?(f+1+m|0)>>>0<=h>>>0:0)n=b;else{B=l+1|0;A=m+1|0;Ub(b,n,e,f,g,h,B,A,B);Ub(b+(Z(h,g)|0)|0,n+(Z(A,B)|0)|0,e,f,g,h,B,A,B);h=A;g=B;e=0;f=0}G=8-j|0;H=8-k|0;B=m>>>1;E=(B|0)==0;A=g<<1;C=l>>>1;F=(C|0)==0;D=16-l|0;z=A-l|0;v=g+1|0;w=A|1;x=g+2|0;y=A+2|0;s=C<<1;u=0;do{l=n+((Z((Z(u,h)|0)+f|0,g)|0)+e)|0;if(!(E|F)){t=c+(u<<6)|0;r=B;while(1){p=d[l+g>>0]|0;m=t;b=l;o=(Z(p,k)|0)+(Z(d[l>>0]|0,H)|0)|0;p=(Z(d[l+A>>0]|0,k)|0)+(Z(p,H)|0)|0;q=C;while(1){K=d[b+v>>0]|0;J=(Z(K,k)|0)+(Z(d[b+1>>0]|0,H)|0)|0;K=(Z(d[b+w>>0]|0,k)|0)+(Z(K,H)|0)|0;M=((Z(o,G)|0)+32+(Z(J,j)|0)|0)>>>6;a[m+8>>0]=((Z(p,G)|0)+32+(Z(K,j)|0)|0)>>>6;a[m>>0]=M;M=b;b=b+2|0;L=d[M+x>>0]|0;o=(Z(L,k)|0)+(Z(d[b>>0]|0,H)|0)|0;p=(Z(d[M+y>>0]|0,k)|0)+(Z(L,H)|0)|0;J=((Z(J,G)|0)+32+(Z(o,j)|0)|0)>>>6;a[m+9>>0]=((Z(K,G)|0)+32+(Z(p,j)|0)|0)>>>6;a[m+1>>0]=J;q=q+-1|0;if(!q)break;else m=m+2|0}r=r+-1|0;if(!r)break;else{t=t+(s+D)|0;l=l+(s+z)|0}}}u=u+1|0}while((u|0)!=2);i=I;return}function Xb(b,c,e,f,g,h,j,k){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;r=i;i=i+448|0;l=r;if(((e|0)>=0?!((j+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)l=b;else{Ub(b,l,e,f,g,h,j,k+5|0,j);g=j;e=0;f=0}h=e+g+(Z(f,g)|0)|0;b=k>>>2;if(!b){i=r;return}n=g<<2;q=0-g|0;o=q<<1;p=g<<1;if(!j){i=r;return}else{m=l+h|0;e=l+(h+(g*5|0))|0}while(1){l=j;h=c;k=m;f=e;while(1){u=d[f+o>>0]|0;v=d[f+q>>0]|0;w=d[f+g>>0]|0;y=d[f>>0]|0;x=w+u|0;s=d[k+p>>0]|0;a[h+48>>0]=a[((d[f+p>>0]|0)+16-x-(x<<2)+s+((y+v|0)*20|0)>>5)+3984>>0]|0;x=s+y|0;t=d[k+g>>0]|0;a[h+32>>0]=a[(w+16-x-(x<<2)+t+((v+u|0)*20|0)>>5)+3984>>0]|0;x=t+v|0;w=d[k>>0]|0;a[h+16>>0]=a[(y+16-x-(x<<2)+w+((s+u|0)*20|0)>>5)+3984>>0]|0;u=w+u|0;a[h>>0]=a[(v+16-u-(u<<2)+(d[k+q>>0]|0)+((t+s|0)*20|0)>>5)+3984>>0]|0;l=l+-1|0;if(!l)break;else{h=h+1|0;k=k+1|0;f=f+1|0}}b=b+-1|0;if(!b)break;else{c=c+64|0;m=m+n|0;e=e+n|0}}i=r;return}function Yb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;v=i;i=i+448|0;m=v;if(((e|0)>=0?!((j+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)m=b;else{Ub(b,m,e,f,g,h,j,k+5|0,j);g=j;e=0;f=0}h=e+g+(Z(f,g)|0)|0;b=k>>>2;if(!b){i=v;return}u=(j|0)==0;s=(g<<2)-j|0;t=64-j|0;r=0-g|0;p=r<<1;q=g<<1;e=m+h|0;f=m+(h+(Z(g,l+2|0)|0))|0;m=m+(h+(g*5|0))|0;while(1){if(u){h=c;k=f}else{k=f+j|0;h=c+j|0;l=j;o=e;n=m;while(1){y=d[n+p>>0]|0;z=d[n+r>>0]|0;A=d[n+g>>0]|0;C=d[n>>0]|0;B=A+y|0;w=d[o+q>>0]|0;a[c+48>>0]=((d[((d[n+q>>0]|0)+16-B-(B<<2)+w+((C+z|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+q>>0]|0)|0)>>>1;B=w+C|0;x=d[o+g>>0]|0;a[c+32>>0]=((d[(A+16-B-(B<<2)+x+((z+y|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+g>>0]|0)|0)>>>1;B=x+z|0;A=d[o>>0]|0;a[c+16>>0]=((d[(C+16-B-(B<<2)+A+((w+y|0)*20|0)>>5)+3984>>0]|0)+1+(d[f>>0]|0)|0)>>>1;y=A+y|0;a[c>>0]=((d[(z+16-y-(y<<2)+(d[o+r>>0]|0)+((x+w|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+r>>0]|0)|0)>>>1;l=l+-1|0;if(!l)break;else{c=c+1|0;o=o+1|0;f=f+1|0;n=n+1|0}}e=e+j|0;m=m+j|0}b=b+-1|0;if(!b)break;else{c=h+t|0;e=e+s|0;f=k+s|0;m=m+s|0}}i=v;return}function Zb(b,c,e,f,g,h,j,k){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;u=i;i=i+448|0;l=u;if((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0|(k+f|0)>>>0>h>>>0):0)l=b;else{n=j+5|0;Ub(b,l,e,f,g,h,n,k,n);g=n;e=0;f=0}if(!k){i=u;return}r=j>>>2;t=(r|0)==0;s=g-j|0;q=16-j|0;p=r<<2;b=c;l=l+(e+5+(Z(f,g)|0))|0;o=k;while(1){if(t)h=b;else{h=b+p|0;e=l;g=d[l+-1>>0]|0;k=d[l+-2>>0]|0;m=d[l+-3>>0]|0;n=d[l+-4>>0]|0;j=d[l+-5>>0]|0;c=r;while(1){f=n+g|0;v=n;n=d[e>>0]|0;a[b>>0]=a[(j+16-f-(f<<2)+n+((m+k|0)*20|0)>>5)+3984>>0]|0;j=n+m|0;f=m;m=d[e+1>>0]|0;a[b+1>>0]=a[(v+16-j-(j<<2)+m+((k+g|0)*20|0)>>5)+3984>>0]|0;j=m+k|0;v=k;k=d[e+2>>0]|0;a[b+2>>0]=a[(f+16-j-(j<<2)+k+((n+g|0)*20|0)>>5)+3984>>0]|0;j=k+g|0;f=d[e+3>>0]|0;a[b+3>>0]=a[(v+16-j-(j<<2)+f+((m+n|0)*20|0)>>5)+3984>>0]|0;c=c+-1|0;if(!c)break;else{j=g;b=b+4|0;e=e+4|0;g=f}}l=l+p|0}o=o+-1|0;if(!o)break;else{b=h+q|0;l=l+s|0}}i=u;return}function _b(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;v=i;i=i+448|0;m=v;if((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0|(k+f|0)>>>0>h>>>0):0)m=b;else{o=j+5|0;Ub(b,m,e,f,g,h,o,k,o);g=o;e=0;f=0}if(!k){i=v;return}s=j>>>2;u=(s|0)==0;t=g-j|0;r=16-j|0;q=(l|0)!=0;p=s<<2;b=c;m=m+(e+5+(Z(f,g)|0))|0;while(1){if(u)h=b;else{h=b+p|0;l=m;e=d[m+-1>>0]|0;g=d[m+-2>>0]|0;n=d[m+-3>>0]|0;o=d[m+-4>>0]|0;j=d[m+-5>>0]|0;c=s;while(1){f=o+e|0;w=o;o=d[l>>0]|0;a[b>>0]=((q?g:n)+1+(d[(j+16-f-(f<<2)+o+((n+g|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=o+n|0;f=n;n=d[l+1>>0]|0;a[b+1>>0]=((q?e:g)+1+(d[(w+16-j-(j<<2)+n+((g+e|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=n+g|0;w=g;g=d[l+2>>0]|0;a[b+2>>0]=((q?o:e)+1+(d[(f+16-j-(j<<2)+g+((o+e|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=g+e|0;f=d[l+3>>0]|0;a[b+3>>0]=((q?n:o)+1+(d[(w+16-j-(j<<2)+f+((n+o|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;c=c+-1|0;if(!c)break;else{j=e;b=b+4|0;l=l+4|0;e=f}}m=m+p|0}k=k+-1|0;if(!k)break;else{b=h+r|0;m=m+t|0}}i=v;return}function $b(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;z=i;i=i+448|0;m=z;if(((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)m=b;else{y=j+5|0;Ub(b,m,e,f,g,h,y,k+5|0,y);g=y;e=0;f=0}b=(Z(f,g)|0)+e|0;y=(l&1|2)+g+b|0;n=m+y|0;if(!k){i=z;return}u=j>>>2;w=(u|0)==0;v=g-j|0;x=16-j|0;t=u<<2;b=m+((Z(g,l>>>1&1|2)|0)+5+b)|0;s=k;while(1){if(!w){r=c+t|0;h=b;e=d[b+-1>>0]|0;f=d[b+-2>>0]|0;o=d[b+-3>>0]|0;p=d[b+-4>>0]|0;l=d[b+-5>>0]|0;q=u;while(1){A=p+e|0;B=p;p=d[h>>0]|0;a[c>>0]=a[(l+16-A-(A<<2)+p+((o+f|0)*20|0)>>5)+3984>>0]|0;A=p+o|0;l=o;o=d[h+1>>0]|0;a[c+1>>0]=a[(B+16-A-(A<<2)+o+((f+e|0)*20|0)>>5)+3984>>0]|0;A=o+f|0;B=f;f=d[h+2>>0]|0;a[c+2>>0]=a[(l+16-A-(A<<2)+f+((p+e|0)*20|0)>>5)+3984>>0]|0;A=f+e|0;l=d[h+3>>0]|0;a[c+3>>0]=a[(B+16-A-(A<<2)+l+((o+p|0)*20|0)>>5)+3984>>0]|0;q=q+-1|0;if(!q)break;else{A=e;c=c+4|0;h=h+4|0;e=l;l=A}}c=r;b=b+t|0}s=s+-1|0;if(!s)break;else{c=c+x|0;b=b+v|0}}b=k>>>2;if(!b){i=z;return}t=(j|0)==0;p=(g<<2)-j|0;o=64-j|0;q=0-g|0;s=q<<1;r=g<<1;c=c+(x-(k<<4))|0;h=m+(y+(g*5|0))|0;l=b;while(1){if(t){b=c;m=n}else{b=c+j|0;m=c;e=n;f=h;c=j;while(1){x=d[f+s>>0]|0;w=d[f+q>>0]|0;u=d[f+g>>0]|0;B=d[f>>0]|0;y=u+x|0;k=d[e+r>>0]|0;A=m+48|0;a[A>>0]=((d[((d[f+r>>0]|0)+16-y-(y<<2)+k+((B+w|0)*20|0)>>5)+3984>>0]|0)+1+(d[A>>0]|0)|0)>>>1;A=k+B|0;y=d[e+g>>0]|0;v=m+32|0;a[v>>0]=((d[(u+16-A-(A<<2)+y+((w+x|0)*20|0)>>5)+3984>>0]|0)+1+(d[v>>0]|0)|0)>>>1;v=d[e>>0]|0;A=y+w|0;u=m+16|0;a[u>>0]=((d[(B+16-A-(A<<2)+v+((k+x|0)*20|0)>>5)+3984>>0]|0)+1+(d[u>>0]|0)|0)>>>1;x=v+x|0;a[m>>0]=((d[(w+16-x-(x<<2)+(d[e+q>>0]|0)+((y+k|0)*20|0)>>5)+3984>>0]|0)+1+(d[m>>0]|0)|0)>>>1;c=c+-1|0;if(!c)break;else{m=m+1|0;e=e+1|0;f=f+1|0}}m=n+j|0;h=h+j|0}l=l+-1|0;if(!l)break;else{c=b+o|0;n=m+p|0;h=h+p|0}}i=z;return}function ac(b,e,f,g,h,j,k,l){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;x=i;i=i+1792|0;m=x+1344|0;w=x;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0){o=l+5|0;m=b;n=f+5|0}else{n=k+5|0;o=l+5|0;Ub(b,m,f,g,h,j,n,o,n);h=n;n=5;g=0}if(o){t=k>>>2;v=(t|0)==0;s=h-k|0;u=t<<2;f=w;m=m+(n+(Z(g,h)|0))|0;while(1){if(v)b=f;else{b=f+(u<<2)|0;g=m;h=d[m+-1>>0]|0;j=d[m+-2>>0]|0;p=d[m+-3>>0]|0;q=d[m+-4>>0]|0;n=d[m+-5>>0]|0;r=t;while(1){y=q+h|0;z=q;q=d[g>>0]|0;c[f>>2]=n-y-(y<<2)+q+((p+j|0)*20|0);y=q+p|0;n=p;p=d[g+1>>0]|0;c[f+4>>2]=z-y+p-(y<<2)+((j+h|0)*20|0);y=p+j|0;z=j;j=d[g+2>>0]|0;c[f+8>>2]=n-y+j-(y<<2)+((q+h|0)*20|0);y=j+h|0;n=d[g+3>>0]|0;c[f+12>>2]=z-y+n-(y<<2)+((p+q|0)*20|0);r=r+-1|0;if(!r)break;else{y=h;f=f+16|0;g=g+4|0;h=n;n=y}}m=m+u|0}o=o+-1|0;if(!o)break;else{f=b;m=m+s|0}}}h=l>>>2;if(!h){i=x;return}u=(k|0)==0;s=64-k|0;p=k*3|0;t=0-k|0;q=t<<1;r=k<<1;g=e;b=w+(k<<2)|0;m=w+(k*6<<2)|0;o=h;while(1){if(u)h=g;else{h=g+k|0;f=b;j=m;n=k;while(1){e=c[j+(q<<2)>>2]|0;w=c[j+(t<<2)>>2]|0;z=c[j+(k<<2)>>2]|0;A=c[j>>2]|0;y=z+e|0;v=c[f+(r<<2)>>2]|0;a[g+48>>0]=a[((c[j+(r<<2)>>2]|0)+512-y-(y<<2)+v+((A+w|0)*20|0)>>10)+3984>>0]|0;y=v+A|0;l=c[f+(k<<2)>>2]|0;a[g+32>>0]=a[(z+512-y-(y<<2)+l+((w+e|0)*20|0)>>10)+3984>>0]|0;y=c[f>>2]|0;z=l+w|0;a[g+16>>0]=a[(A+512-z-(z<<2)+y+((v+e|0)*20|0)>>10)+3984>>0]|0;e=y+e|0;a[g>>0]=a[(w+512-e-(e<<2)+(c[f+(t<<2)>>2]|0)+((l+v|0)*20|0)>>10)+3984>>0]|0;n=n+-1|0;if(!n)break;else{g=g+1|0;f=f+4|0;j=j+4|0}}b=b+(k<<2)|0;m=m+(k<<2)|0}o=o+-1|0;if(!o)break;else{g=h+s|0;b=b+(p<<2)|0;m=m+(p<<2)|0}}i=x;return}function bc(b,e,f,g,h,j,k,l,m){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;y=i;i=i+1792|0;n=y+1344|0;x=y;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0){o=l+5|0;n=b;f=f+5|0}else{q=k+5|0;o=l+5|0;Ub(b,n,f,g,h,j,q,o,q);h=q;f=5;g=0}if(o){v=k>>>2;t=(v|0)==0;u=h-k|0;w=v<<2;p=x;n=n+(f+(Z(g,h)|0))|0;s=o;while(1){if(t)b=p;else{b=p+(w<<2)|0;g=n;f=d[n+-1>>0]|0;h=d[n+-2>>0]|0;j=d[n+-3>>0]|0;q=d[n+-4>>0]|0;o=d[n+-5>>0]|0;r=v;while(1){z=q+f|0;A=q;q=d[g>>0]|0;c[p>>2]=o-z-(z<<2)+q+((j+h|0)*20|0);z=q+j|0;o=j;j=d[g+1>>0]|0;c[p+4>>2]=A-z+j-(z<<2)+((h+f|0)*20|0);z=j+h|0;A=h;h=d[g+2>>0]|0;c[p+8>>2]=o-z+h-(z<<2)+((q+f|0)*20|0);z=h+f|0;o=d[g+3>>0]|0;c[p+12>>2]=A-z+o-(z<<2)+((j+q|0)*20|0);r=r+-1|0;if(!r)break;else{z=f;p=p+16|0;g=g+4|0;f=o;o=z}}n=n+w|0}s=s+-1|0;if(!s)break;else{p=b;n=n+u|0}}}f=l>>>2;if(!f){i=y;return}w=(k|0)==0;u=64-k|0;q=k*3|0;v=0-k|0;t=v<<1;s=k<<1;b=x+(k<<2)|0;n=x+((Z(m+2|0,k)|0)+k<<2)|0;h=x+(k*6<<2)|0;r=f;while(1){if(w){g=e;f=n}else{f=n+(k<<2)|0;g=e+k|0;p=b;j=h;o=k;while(1){m=c[j+(t<<2)>>2]|0;l=c[j+(v<<2)>>2]|0;B=c[j+(k<<2)>>2]|0;C=c[j>>2]|0;A=B+m|0;z=c[p+(s<<2)>>2]|0;a[e+48>>0]=((d[((c[j+(s<<2)>>2]|0)+512-A-(A<<2)+z+((C+l|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(s<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;A=z+C|0;x=c[p+(k<<2)>>2]|0;a[e+32>>0]=((d[(B+512-A-(A<<2)+x+((l+m|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(k<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;A=c[p>>2]|0;B=x+l|0;a[e+16>>0]=((d[(C+512-B-(B<<2)+A+((z+m|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=A+m|0;a[e>>0]=((d[(l+512-m-(m<<2)+(c[p+(v<<2)>>2]|0)+((x+z|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(v<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;o=o+-1|0;if(!o)break;else{e=e+1|0;p=p+4|0;n=n+4|0;j=j+4|0}}b=b+(k<<2)|0;h=h+(k<<2)|0}r=r+-1|0;if(!r)break;else{e=g+u|0;b=b+(q<<2)|0;n=f+(q<<2)|0;h=h+(q<<2)|0}}i=y;return}function cc(b,e,f,g,h,j,k,l,m){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;B=i;i=i+1792|0;n=B+1344|0;A=B;z=k+5|0;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0)n=b;else{Ub(b,n,f,g,h,j,z,l+5|0,z);h=z;f=0;g=0}s=f+h+(Z(g,h)|0)|0;g=l>>>2;if(g){y=(z|0)==0;x=(h<<2)-k+-5|0;t=z*3|0;p=0-h|0;w=p<<1;v=h<<1;u=z<<1;q=-5-k|0;j=A+(z<<2)|0;r=n+s|0;f=n+(s+(h*5|0))|0;while(1){if(y)s=j;else{s=j+(z<<2)|0;n=r;b=f;o=z;while(1){E=d[b+w>>0]|0;F=d[b+p>>0]|0;H=d[b+h>>0]|0;I=d[b>>0]|0;G=H+E|0;C=d[n+v>>0]|0;c[j+(u<<2)>>2]=(d[b+v>>0]|0)-G-(G<<2)+C+((I+F|0)*20|0);G=C+I|0;D=d[n+h>>0]|0;c[j+(z<<2)>>2]=H-G+D-(G<<2)+((F+E|0)*20|0);G=d[n>>0]|0;H=D+F|0;c[j>>2]=I-H+G-(H<<2)+((C+E|0)*20|0);E=G+E|0;c[j+(q<<2)>>2]=F-E+(d[n+p>>0]|0)-(E<<2)+((D+C|0)*20|0);o=o+-1|0;if(!o)break;else{j=j+4|0;n=n+1|0;b=b+1|0}}r=r+z|0;f=f+z|0}g=g+-1|0;if(!g)break;else{j=s+(t<<2)|0;r=r+x|0;f=f+x|0}}}if(!l){i=B;return}v=k>>>2;w=(v|0)==0;u=16-k|0;t=v<<2;h=A+(m+2<<2)|0;g=A+20|0;while(1){if(w)f=h;else{f=h+(t<<2)|0;s=e;n=g;j=c[g+-4>>2]|0;o=c[g+-8>>2]|0;p=c[g+-12>>2]|0;q=c[g+-16>>2]|0;b=c[g+-20>>2]|0;r=v;while(1){m=q+j|0;k=q;q=c[n>>2]|0;a[s>>0]=((d[(b+512-m-(m<<2)+q+((p+o|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=q+p|0;b=p;p=c[n+4>>2]|0;a[s+1>>0]=((d[(k+512-m-(m<<2)+p+((o+j|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+4>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=p+o|0;k=o;o=c[n+8>>2]|0;a[s+2>>0]=((d[(b+512-m-(m<<2)+o+((q+j|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+8>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=o+j|0;b=c[n+12>>2]|0;a[s+3>>0]=((d[(k+512-m-(m<<2)+b+((p+q|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+12>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;r=r+-1|0;if(!r)break;else{m=j;s=s+4|0;h=h+16|0;n=n+16|0;j=b;b=m}}e=e+t|0;g=g+(t<<2)|0}l=l+-1|0;if(!l)break;else{e=e+u|0;h=f+20|0;g=g+20|0}}i=B;return}function dc(a,d,e,f,g,h,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;x=i;q=a+((j<<4)+h)|0;u=b[d>>1]|0;w=d+2|0;t=b[w>>1]|0;s=e+4|0;p=c[s>>2]<<4;r=e+8|0;o=c[r>>2]<<4;f=h+f|0;m=f+(u>>2)|0;g=j+g|0;n=g+(t>>2)|0;do switch(c[6800+((u&3)<<4)+((t&3)<<2)>>2]|0){case 10:{ac(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l);break}case 6:{cc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 4:{_b(c[e>>2]|0,q,m+-2|0,n,p,o,k,l,0);break}case 1:{Yb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l,0);break}case 2:{Xb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l);break}case 12:{_b(c[e>>2]|0,q,m+-2|0,n,p,o,k,l,1);break}case 14:{cc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}case 7:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,2);break}case 13:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}case 5:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 0:{Ub(c[e>>2]|0,q,m,n,p,o,k,l,16);break}case 9:{bc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 8:{Zb(c[e>>2]|0,q,m+-2|0,n,p,o,k,l);break}case 3:{Yb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l,1);break}case 11:{bc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}default:$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,3)}while(0);u=(h>>>1)+256+(j>>>1<<3)|0;v=a+u|0;t=c[e>>2]|0;m=c[s>>2]|0;j=c[r>>2]|0;r=m<<3;s=j<<3;p=b[d>>1]|0;e=(p>>3)+(f>>>1)|0;q=b[w>>1]|0;o=(q>>3)+(g>>>1)|0;p=p&7;q=q&7;g=k>>>1;h=l>>>1;j=Z(m<<8,j)|0;f=t+j|0;m=(p|0)!=0;n=(q|0)!=0;if(m&n){Wb(f,v,e,o,r,s,p,q,g,h);i=x;return}if(m){Tb(f,v,e,o,r,s,p,g,h);i=x;return}if(n){Vb(f,v,e,o,r,s,q,g,h);i=x;return}else{Ub(f,v,e,o,r,s,g,h,8);Ub(t+((Z(s,r)|0)+j)|0,a+(u+64)|0,e,o,r,s,g,h,8);i=x;return}}function ec(b,c,d,e,f){b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0;j=i;if(d){nd(c|0,a[b>>0]|0,d|0)|0;c=c+d|0}if(e){h=c+e|0;g=e;d=b;while(1){a[c>>0]=a[d>>0]|0;g=g+-1|0;if(!g)break;else{c=c+1|0;d=d+1|0}}c=h;b=b+e|0}if(!f){i=j;return}nd(c|0,a[b+-1>>0]|0,f|0)|0;i=j;return}function fc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;c=i;hd(b,a,d);i=c;return}function gc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;f=c[a+40>>2]|0;if(f){h=c[a>>2]|0;k=a+32|0;j=0;do{if(((c[h+(j*40|0)+20>>2]|0)+-1|0)>>>0<2){g=c[h+(j*40|0)+12>>2]|0;if(g>>>0>d>>>0)g=g-(c[k>>2]|0)|0;c[h+(j*40|0)+8>>2]=g}j=j+1|0}while((j|0)!=(f|0))}if(!(c[b>>2]|0)){p=0;i=q;return p|0}g=c[b+4>>2]|0;if(g>>>0>=3){p=0;i=q;return p|0}o=a+32|0;p=a+24|0;n=a+4|0;f=d;m=0;a:while(1){b:do if(g>>>0<2){k=c[b+(m*12|0)+8>>2]|0;if(!g){g=f-k|0;if((g|0)<0)g=(c[o>>2]|0)+g|0}else{l=k+f|0;g=c[o>>2]|0;g=l-((l|0)<(g|0)?0:g)|0}if(g>>>0>d>>>0)f=g-(c[o>>2]|0)|0;else f=g;j=c[p>>2]|0;if(!j){f=1;g=37;break a}k=c[a>>2]|0;l=0;while(1){h=c[k+(l*40|0)+20>>2]|0;if((h+-1|0)>>>0<2?(c[k+(l*40|0)+8>>2]|0)==(f|0):0){f=g;break b}l=l+1|0;if(l>>>0>=j>>>0){f=1;g=37;break a}}}else{j=c[b+(m*12|0)+12>>2]|0;h=c[p>>2]|0;if(!h){f=1;g=37;break a}k=c[a>>2]|0;g=0;while(1){if((c[k+(g*40|0)+20>>2]|0)==3?(c[k+(g*40|0)+8>>2]|0)==(j|0):0){h=3;l=g;break b}g=g+1|0;if(g>>>0>=h>>>0){f=1;g=37;break a}}}while(0);if(!((l|0)>-1&h>>>0>1)){f=1;g=37;break}if(m>>>0>>0){k=e;do{j=k;k=k+-1|0;h=c[n>>2]|0;c[h+(j<<2)>>2]=c[h+(k<<2)>>2]}while(k>>>0>m>>>0);k=c[a>>2]|0}c[(c[n>>2]|0)+(m<<2)>>2]=k+(l*40|0);m=m+1|0;if(m>>>0<=e>>>0){g=m;k=m;do{j=c[n>>2]|0;h=c[j+(g<<2)>>2]|0;if((h|0)!=((c[a>>2]|0)+(l*40|0)|0)){c[j+(k<<2)>>2]=h;k=k+1|0}g=g+1|0}while(g>>>0<=e>>>0)}g=c[b+(m*12|0)+4>>2]|0;if(g>>>0>=3){f=0;g=37;break}}if((g|0)==37){i=q;return f|0}return 0}function hc(a,b,d,e,f,g,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0;K=i;I=c[d>>2]|0;J=c[a+8>>2]|0;if((I|0)!=(c[J>>2]|0)){D=1;i=K;return D|0}B=a+52|0;c[B>>2]=0;G=c[a+56>>2]|0;o=(G|0)==0;H=o&1;do if(!b){c[J+20>>2]=0;c[J+12>>2]=e;c[J+8>>2]=e;c[J+16>>2]=f;c[J+24>>2]=H;if(o){d=a+44|0;c[d>>2]=(c[d>>2]|0)+1;d=0;r=0}else{d=G;r=0}}else{if(g){k=a+20|0;c[k>>2]=0;l=a+16|0;c[l>>2]=0;r=c[a>>2]|0;s=a+44|0;q=0;do{p=r+(q*40|0)+20|0;if((c[p>>2]|0)!=0?(c[p>>2]=0,(c[r+(q*40|0)+24>>2]|0)==0):0)c[s>>2]=(c[s>>2]|0)+-1;q=q+1|0}while((q|0)!=16);a:do if(o){n=c[a+28>>2]|0;m=a+12|0;q=0;while(1){e=0;p=2147483647;o=0;do{if(c[r+(e*40|0)+24>>2]|0){C=c[r+(e*40|0)+16>>2]|0;D=(C|0)<(p|0);p=D?C:p;o=D?r+(e*40|0)|0:o}e=e+1|0}while(e>>>0<=n>>>0);if(!o){d=0;break a}D=c[m>>2]|0;c[D+(q<<4)>>2]=c[o>>2];c[D+(q<<4)+12>>2]=c[o+36>>2];c[D+(q<<4)+4>>2]=c[o+28>>2];c[D+(q<<4)+8>>2]=c[o+32>>2];q=q+1|0;c[l>>2]=q;c[o+24>>2]=0;if(c[o+20>>2]|0)continue;c[s>>2]=(c[s>>2]|0)+-1}}else d=G;while(0);p=a+40|0;c[p>>2]=0;o=a+36|0;c[o>>2]=65535;c[a+48>>2]=0;if(!(c[b>>2]|d))d=0;else{c[l>>2]=0;c[k>>2]=0}r=(c[b+4>>2]|0)==0;c[J+20>>2]=r?2:3;c[o>>2]=r?65535:0;c[J+12>>2]=0;c[J+8>>2]=0;c[J+16>>2]=0;c[J+24>>2]=H;c[s>>2]=1;c[p>>2]=1;r=0;break}if(!(c[b+8>>2]|0)){d=a+40|0;q=c[d>>2]|0;p=c[a+24>>2]|0;if(q>>>0>=p>>>0)if(q){l=c[a>>2]|0;m=0;o=-1;n=0;do{if(((c[l+(m*40|0)+20>>2]|0)+-1|0)>>>0<2){D=c[l+(m*40|0)+8>>2]|0;C=(D|0)<(n|0)|(o|0)==-1;o=C?m:o;n=C?D:n}m=m+1|0}while((m|0)!=(q|0));if((o|0)>-1){q=q+-1|0;c[l+(o*40|0)+20>>2]=0;c[d>>2]=q;if(!(c[l+(o*40|0)+24>>2]|0)){d=a+44|0;c[d>>2]=(c[d>>2]|0)+-1;d=G;n=0}else{d=G;n=0}}else{d=G;n=1}}else{q=0;d=G;n=1}else{d=G;n=0}}else{E=a+24|0;C=a+40|0;v=a+44|0;x=a+36|0;A=a+48|0;u=a+28|0;y=a+16|0;z=a+12|0;r=G;d=G;t=0;w=0;b:while(1){switch(c[b+(t*20|0)+12>>2]|0){case 4:{l=c[b+(t*20|0)+28>>2]|0;c[x>>2]=l;m=c[E>>2]|0;if(!m)s=w;else{n=c[a>>2]|0;s=l;o=0;do{k=n+(o*40|0)+20|0;do if((c[k>>2]|0)==3){if((c[n+(o*40|0)+8>>2]|0)>>>0<=l>>>0)if((s|0)==65535)s=65535;else break;c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[n+(o*40|0)+24>>2]|0))c[v>>2]=(c[v>>2]|0)+-1}while(0);o=o+1|0}while((o|0)!=(m|0));s=w}break}case 1:{n=e-(c[b+(t*20|0)+16>>2]|0)|0;l=c[E>>2]|0;if(!l){n=1;break b}m=c[a>>2]|0;s=0;while(1){k=m+(s*40|0)+20|0;if(((c[k>>2]|0)+-1|0)>>>0<2?(c[m+(s*40|0)+8>>2]|0)==(n|0):0)break;s=s+1|0;if(s>>>0>=l>>>0){n=1;break b}}if((s|0)<0){n=1;break b}c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[m+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=w}else s=w;break}case 6:{m=c[b+(t*20|0)+24>>2]|0;s=c[x>>2]|0;if((s|0)==65535|s>>>0>>0){n=1;F=101;break b}r=c[E>>2]|0;c:do if(r){l=c[a>>2]|0;s=0;while(1){k=l+(s*40|0)+20|0;if((c[k>>2]|0)==3?(c[l+(s*40|0)+8>>2]|0)==(m|0):0)break;s=s+1|0;if(s>>>0>=r>>>0){F=88;break c}}c[k>>2]=0;k=(c[C>>2]|0)+-1|0;c[C>>2]=k;if(!(c[l+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=k}else s=k}else{r=0;F=88}while(0);if((F|0)==88){F=0;s=c[C>>2]|0}if(s>>>0>=r>>>0){n=1;F=101;break b}c[J+12>>2]=e;c[J+8>>2]=m;c[J+16>>2]=f;c[J+20>>2]=3;c[J+24>>2]=H;c[C>>2]=s+1;c[v>>2]=(c[v>>2]|0)+1;r=G;d=G;s=1;break}case 2:{l=c[b+(t*20|0)+20>>2]|0;m=c[E>>2]|0;if(!m){n=1;break b}n=c[a>>2]|0;s=0;while(1){k=n+(s*40|0)+20|0;if((c[k>>2]|0)==3?(c[n+(s*40|0)+8>>2]|0)==(l|0):0)break;s=s+1|0;if(s>>>0>=m>>>0){n=1;break b}}if((s|0)<0){n=1;break b}c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[n+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=w}else s=w;break}case 3:{s=c[b+(t*20|0)+16>>2]|0;n=c[b+(t*20|0)+24>>2]|0;k=c[x>>2]|0;if((k|0)==65535|k>>>0>>0){n=1;break b}o=c[E>>2]|0;if(!o){n=1;break b}p=c[a>>2]|0;k=0;while(1){m=p+(k*40|0)+20|0;if((c[m>>2]|0)==3?(c[p+(k*40|0)+8>>2]|0)==(n|0):0){F=47;break}l=k+1|0;if(l>>>0>>0)k=l;else break}if((F|0)==47?(F=0,c[m>>2]=0,c[C>>2]=(c[C>>2]|0)+-1,(c[p+(k*40|0)+24>>2]|0)==0):0)c[v>>2]=(c[v>>2]|0)+-1;m=e-s|0;s=0;while(1){l=p+(s*40|0)+20|0;k=c[l>>2]|0;if((k+-1|0)>>>0<2?(D=p+(s*40|0)+8|0,(c[D>>2]|0)==(m|0)):0)break;s=s+1|0;if(s>>>0>=o>>>0){n=1;break b}}if(!((s|0)>-1&k>>>0>1)){n=1;break b}c[l>>2]=3;c[D>>2]=n;s=w;break}case 5:{n=c[a>>2]|0;q=0;do{p=n+(q*40|0)+20|0;if((c[p>>2]|0)!=0?(c[p>>2]=0,(c[n+(q*40|0)+24>>2]|0)==0):0)c[v>>2]=(c[v>>2]|0)+-1;q=q+1|0}while((q|0)!=16);d:do if(!d){l=c[u>>2]|0;m=r;while(1){d=0;s=2147483647;k=0;do{if(c[n+(d*40|0)+24>>2]|0){o=c[n+(d*40|0)+16>>2]|0;e=(o|0)<(s|0);s=e?o:s;k=e?n+(d*40|0)|0:k}d=d+1|0}while(d>>>0<=l>>>0);if(!k){r=m;d=0;break d}s=c[y>>2]|0;d=c[z>>2]|0;c[d+(s<<4)>>2]=c[k>>2];c[d+(s<<4)+12>>2]=c[k+36>>2];c[d+(s<<4)+4>>2]=c[k+28>>2];c[d+(s<<4)+8>>2]=c[k+32>>2];c[y>>2]=s+1;c[k+24>>2]=0;if(!(c[k+20>>2]|0))c[v>>2]=(c[v>>2]|0)+-1;if(!m)m=0;else{r=m;d=m;break}}}while(0);c[C>>2]=0;c[x>>2]=65535;c[A>>2]=0;c[B>>2]=1;e=0;s=w;break}case 0:{n=0;F=101;break b}default:{n=1;break b}}t=t+1|0;w=s}if(w){r=n;break}q=c[C>>2]|0;p=c[E>>2]|0}if(q>>>0

>>0){c[J+12>>2]=e;c[J+8>>2]=e;c[J+16>>2]=f;c[J+20>>2]=2;c[J+24>>2]=H;r=a+44|0;c[r>>2]=(c[r>>2]|0)+1;c[a+40>>2]=q+1;r=n}else r=1}while(0);c[J+36>>2]=g;c[J+28>>2]=h;c[J+32>>2]=j;if(!d){o=a+44|0;d=c[o>>2]|0;k=c[a+28>>2]|0;if(d>>>0>k>>>0){p=a+16|0;q=a+12|0;do{n=c[a>>2]|0;e=0;l=2147483647;m=0;do{if(c[n+(e*40|0)+24>>2]|0){C=c[n+(e*40|0)+16>>2]|0;D=(C|0)<(l|0);l=D?C:l;m=D?n+(e*40|0)|0:m}e=e+1|0}while(e>>>0<=k>>>0);if((m|0)!=0?(D=c[p>>2]|0,C=c[q>>2]|0,c[C+(D<<4)>>2]=c[m>>2],c[C+(D<<4)+12>>2]=c[m+36>>2],c[C+(D<<4)+4>>2]=c[m+28>>2],c[C+(D<<4)+8>>2]=c[m+32>>2],c[p>>2]=D+1,c[m+24>>2]=0,(c[m+20>>2]|0)==0):0){d=d+-1|0;c[o>>2]=d}}while(d>>>0>k>>>0)}}else{k=a+16|0;D=c[k>>2]|0;C=c[a+12>>2]|0;c[C+(D<<4)>>2]=I;c[C+(D<<4)+12>>2]=g;c[C+(D<<4)+4>>2]=h;c[C+(D<<4)+8>>2]=j;c[k>>2]=D+1;k=c[a+28>>2]|0}rc(c[a>>2]|0,k+1|0);D=r;i=K;return D|0}function ic(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;if((b>>>0<=16?(d=c[(c[a+4>>2]|0)+(b<<2)>>2]|0,(d|0)!=0):0)?(c[d+20>>2]|0)>>>0>1:0)d=c[d>>2]|0;else d=0;i=e;return d|0}function jc(a){a=a|0;var b=0;b=(c[a>>2]|0)+((c[a+28>>2]|0)*40|0)|0;c[a+8>>2]=b;return c[b>>2]|0}function kc(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0;j=i;c[a+36>>2]=65535;e=e>>>0>1?e:1;c[a+24>>2]=e;h=a+28|0;c[h>>2]=(g|0)==0?d:e;c[a+32>>2]=f;c[a+56>>2]=g;c[a+44>>2]=0;c[a+40>>2]=0;c[a+48>>2]=0;g=fd(680)|0;c[a>>2]=g;if(!g){g=65535;i=j;return g|0}id(g,0,680);a:do if((c[h>>2]|0)!=-1){f=b*384|47;e=0;while(1){d=fd(f)|0;g=c[a>>2]|0;c[g+(e*40|0)+4>>2]=d;if(!d){g=65535;break}c[g+(e*40|0)>>2]=d+(0-d&15);e=e+1|0;if(e>>>0>=((c[h>>2]|0)+1|0)>>>0)break a}i=j;return g|0}while(0);g=a+4|0;c[g>>2]=fd(68)|0;f=fd((c[h>>2]<<4)+16|0)|0;c[a+12>>2]=f;g=c[g>>2]|0;if((g|0)==0|(f|0)==0){g=65535;i=j;return g|0}id(g,0,68);c[a+20>>2]=0;c[a+16>>2]=0;g=0;i=j;return g|0}function lc(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0;l=i;h=c[a>>2]|0;if(h){k=a+28|0;if((c[k>>2]|0)!=-1){j=0;do{gd(c[h+(j*40|0)+4>>2]|0);h=c[a>>2]|0;c[h+(j*40|0)+4>>2]=0;j=j+1|0}while(j>>>0<((c[k>>2]|0)+1|0)>>>0)}}else h=0;gd(h);c[a>>2]=0;h=a+4|0;gd(c[h>>2]|0);c[h>>2]=0;h=a+12|0;gd(c[h>>2]|0);c[h>>2]=0;h=kc(a,b,d,e,f,g)|0;i=l;return h|0}function mc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;b=c[a>>2]|0;if(b){e=a+28|0;if((c[e>>2]|0)!=-1){d=0;do{gd(c[b+(d*40|0)+4>>2]|0);b=c[a>>2]|0;c[b+(d*40|0)+4>>2]=0;d=d+1|0}while(d>>>0<((c[e>>2]|0)+1|0)>>>0)}}else b=0;gd(b);c[a>>2]=0;b=a+4|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+12|0;gd(c[b>>2]|0);c[b>>2]=0;i=f;return}function nc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;b=c[a+40>>2]|0;if(!b){i=f;return}e=a+4|0;d=0;do{c[(c[e>>2]|0)+(d<<2)>>2]=(c[a>>2]|0)+(d*40|0);d=d+1|0}while(d>>>0>>0);i=f;return}function oc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;y=i;v=a+16|0;c[v>>2]=0;c[a+20>>2]=0;if(!e){b=0;i=y;return b|0}x=a+48|0;e=c[x>>2]|0;f=(e|0)==(b|0);a:do if(!f?(u=a+32|0,l=c[u>>2]|0,k=((e+1|0)>>>0)%(l>>>0)|0,(k|0)!=(b|0)):0){t=a+28|0;w=c[(c[a>>2]|0)+((c[t>>2]|0)*40|0)>>2]|0;r=a+40|0;p=a+24|0;o=a+44|0;q=a+56|0;s=a+12|0;n=k;while(1){k=c[r>>2]|0;if(!k)k=0;else{j=c[a>>2]|0;h=0;do{if(((c[j+(h*40|0)+20>>2]|0)+-1|0)>>>0<2){e=c[j+(h*40|0)+12>>2]|0;c[j+(h*40|0)+8>>2]=e-(e>>>0>n>>>0?l:0)}h=h+1|0}while((h|0)!=(k|0))}if(k>>>0>=(c[p>>2]|0)>>>0){if(!k){e=1;g=46;break}f=c[a>>2]|0;h=0;l=-1;j=0;while(1){if(((c[f+(h*40|0)+20>>2]|0)+-1|0)>>>0<2){e=c[f+(h*40|0)+8>>2]|0;m=(e|0)<(j|0)|(l|0)==-1;g=m?h:l;j=m?e:j}else g=l;h=h+1|0;if((h|0)==(k|0))break;else l=g}if((g|0)<=-1){e=1;g=46;break}l=k+-1|0;c[f+(g*40|0)+20>>2]=0;c[r>>2]=l;if(!(c[f+(g*40|0)+24>>2]|0)){c[o>>2]=(c[o>>2]|0)+-1;k=l}else k=l}l=c[o>>2]|0;m=c[t>>2]|0;if(l>>>0>=m>>>0){e=(c[q>>2]|0)==0;do if(e){g=c[a>>2]|0;f=0;j=2147483647;h=0;do{if(c[g+(f*40|0)+24>>2]|0){A=c[g+(f*40|0)+16>>2]|0;z=(A|0)<(j|0);j=z?A:j;h=z?g+(f*40|0)|0:h}f=f+1|0}while(f>>>0<=m>>>0);if((h|0)!=0?(f=c[v>>2]|0,g=c[s>>2]|0,c[g+(f<<4)>>2]=c[h>>2],c[g+(f<<4)+12>>2]=c[h+36>>2],c[g+(f<<4)+4>>2]=c[h+28>>2],c[g+(f<<4)+8>>2]=c[h+32>>2],c[v>>2]=f+1,c[h+24>>2]=0,(c[h+20>>2]|0)==0):0){l=l+-1|0;c[o>>2]=l}}while(l>>>0>=m>>>0)}e=c[a>>2]|0;c[e+(m*40|0)+20>>2]=1;c[e+(m*40|0)+12>>2]=n;c[e+(m*40|0)+8>>2]=n;c[e+(m*40|0)+16>>2]=0;c[e+(m*40|0)+24>>2]=0;c[o>>2]=l+1;c[r>>2]=k+1;rc(e,m+1|0);l=c[u>>2]|0;n=((n+1|0)>>>0)%(l>>>0)|0;if((n|0)==(b|0)){g=31;break}}if((g|0)==31){g=c[v>>2]|0;if(!g){g=41;break}e=c[s>>2]|0;h=c[t>>2]|0;j=c[a>>2]|0;l=j+(h*40|0)|0;k=c[l>>2]|0;f=0;while(1){if((c[e+(f<<4)>>2]|0)==(k|0))break;f=f+1|0;if(f>>>0>=g>>>0){g=41;break a}}if(!h){g=41;break}else e=0;while(1){f=j+(e*40|0)|0;e=e+1|0;if((c[f>>2]|0)==(w|0))break;if(e>>>0>=h>>>0){g=41;break a}}c[f>>2]=k;c[l>>2]=w;g=41;break}else if((g|0)==46){i=y;return e|0}}else g=39;while(0);if((g|0)==39)if(d)if(f){b=1;i=y;return b|0}else g=41;do if((g|0)==41){if(!d){e=c[x>>2]|0;break}c[x>>2]=b;b=0;i=y;return b|0}while(0);if((e|0)==(b|0)){b=0;i=y;return b|0}a=c[a+32>>2]|0;c[x>>2]=((b+-1+a|0)>>>0)%(a>>>0)|0;b=0;i=y;return b|0}function pc(a){a=a|0;var b=0,d=0,e=0;e=i;d=a+20|0;b=c[d>>2]|0;if(b>>>0>=(c[a+16>>2]|0)>>>0){b=0;i=e;return b|0}a=c[a+12>>2]|0;c[d>>2]=b+1;b=a+(b<<4)|0;i=e;return b|0}function qc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;k=i;f=c[a>>2]|0;if(!f){i=k;return}c[a+60>>2]=1;if(c[a+56>>2]|0){i=k;return}g=c[a+28>>2]|0;h=a+16|0;j=a+12|0;e=a+44|0;a=0;b=2147483647;d=0;while(1){if(c[f+(a*40|0)+24>>2]|0){m=c[f+(a*40|0)+16>>2]|0;l=(m|0)<(b|0);b=l?m:b;d=l?f+(a*40|0)|0:d}a=a+1|0;if(a>>>0<=g>>>0)continue;if(!d)break;l=c[h>>2]|0;b=c[j>>2]|0;c[b+(l<<4)>>2]=c[d>>2];c[b+(l<<4)+12>>2]=c[d+36>>2];c[b+(l<<4)+4>>2]=c[d+28>>2];c[b+(l<<4)+8>>2]=c[d+32>>2];c[h>>2]=l+1;c[d+24>>2]=0;if(c[d+20>>2]|0){a=0;b=2147483647;d=0;continue}c[e>>2]=(c[e>>2]|0)+-1;a=0;b=2147483647;d=0}i=k;return}function rc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=i;i=i+32|0;q=v+16|0;t=v;o=7;do{if(o>>>0>>0){n=o;do{m=a+(n*40|0)|0;l=c[m>>2]|0;m=c[m+4>>2]|0;p=c[a+(n*40|0)+8>>2]|0;k=a+(n*40|0)+12|0;s=c[k+4>>2]|0;r=q;c[r>>2]=c[k>>2];c[r+4>>2]=s;r=c[a+(n*40|0)+20>>2]|0;s=c[a+(n*40|0)+24>>2]|0;k=a+(n*40|0)+28|0;c[t+0>>2]=c[k+0>>2];c[t+4>>2]=c[k+4>>2];c[t+8>>2]=c[k+8>>2];a:do if(n>>>0>>0){d=n;u=8}else{f=(s|0)==0;j=r+-1|0;k=j>>>0<2;b:do if(!r){e=n;while(1){d=e-o|0;if(c[a+(d*40|0)+20>>2]|0){d=e;break b}if((c[a+(d*40|0)+24>>2]|0)!=0|f){d=e;break b}e=a+(e*40|0)+0|0;g=a+(d*40|0)+0|0;h=e+40|0;do{c[e>>2]=c[g>>2];e=e+4|0;g=g+4|0}while((e|0)<(h|0));if(d>>>0>>0){u=8;break a}else e=d}}else{d=n;while(1){f=d-o|0;e=c[a+(f*40|0)+20>>2]|0;do if(e){e=e+-1|0;if((e|j)>>>0<2){e=c[a+(f*40|0)+8>>2]|0;if((e|0)>(p|0))break b;d=a+(d*40|0)|0;if((e|0)<(p|0))break;else break a}if(e>>>0<2)break b;if(!k?(c[a+(f*40|0)+8>>2]|0)<=(p|0):0)break b;else u=16}else u=16;while(0);if((u|0)==16){u=0;d=a+(d*40|0)|0}e=d+0|0;g=a+(f*40|0)+0|0;h=e+40|0;do{c[e>>2]=c[g>>2];e=e+4|0;g=g+4|0}while((e|0)<(h|0));if(f>>>0>>0){d=f;u=8;break a}else d=f}}while(0);d=a+(d*40|0)|0}while(0);if((u|0)==8){u=0;d=a+(d*40|0)|0}k=d;c[k>>2]=l;c[k+4>>2]=m;c[d+8>>2]=p;k=q;l=c[k+4>>2]|0;m=d+12|0;c[m>>2]=c[k>>2];c[m+4>>2]=l;c[d+20>>2]=r;c[d+24>>2]=s;m=d+28|0;c[m+0>>2]=c[t+0>>2];c[m+4>>2]=c[t+4>>2];c[m+8>>2]=c[t+8>>2];n=n+1|0}while((n|0)!=(b|0))}o=o>>>1}while((o|0)!=0);i=v;return}function sc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;e=c[a+4>>2]|0;f=c[a+16>>2]|0;g=c[a+20>>2]|0;j=e<<2;k=b+256|0;h=16;a=c[a+12>>2]|0;d=b;while(1){m=c[d+4>>2]|0;c[a>>2]=c[d>>2];c[a+4>>2]=m;m=c[d+12>>2]|0;c[a+8>>2]=c[d+8>>2];c[a+12>>2]=m;h=h+-1|0;if(!h)break;else{a=a+(j<<2)|0;d=d+16|0}}j=e<<1&2147483646;h=c[b+260>>2]|0;c[f>>2]=c[k>>2];c[f+4>>2]=h;k=c[b+268>>2]|0;c[f+(j<<2)>>2]=c[b+264>>2];c[f+((j|1)<<2)>>2]=k;k=e<<2;h=c[b+276>>2]|0;c[f+(k<<2)>>2]=c[b+272>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+284>>2]|0;c[f+(k<<2)>>2]=c[b+280>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+292>>2]|0;c[f+(k<<2)>>2]=c[b+288>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+300>>2]|0;c[f+(k<<2)>>2]=c[b+296>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+308>>2]|0;c[f+(k<<2)>>2]=c[b+304>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+316>>2]|0;c[f+(k<<2)>>2]=c[b+312>>2];c[f+((k|1)<<2)>>2]=h;k=c[b+324>>2]|0;c[g>>2]=c[b+320>>2];c[g+4>>2]=k;k=c[b+332>>2]|0;c[g+(j<<2)>>2]=c[b+328>>2];c[g+((j|1)<<2)>>2]=k;k=e<<2;h=c[b+340>>2]|0;c[g+(k<<2)>>2]=c[b+336>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+348>>2]|0;c[g+(k<<2)>>2]=c[b+344>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+356>>2]|0;c[g+(k<<2)>>2]=c[b+352>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+364>>2]|0;c[g+(k<<2)>>2]=c[b+360>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+372>>2]|0;c[g+(k<<2)>>2]=c[b+368>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;j=c[b+380>>2]|0;c[g+(k<<2)>>2]=c[b+376>>2];c[g+((k|1)<<2)>>2]=j;i=l;return}function tc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;y=i;r=c[b+4>>2]|0;s=Z(c[b+8>>2]|0,r)|0;w=(e>>>0)%(r>>>0)|0;x=c[b>>2]|0;u=e-w|0;b=(u<<8)+(w<<4)|0;v=s<<8;w=w<<3;p=r<<4;o=r<<2&1073741820;l=o<<1;m=l+o|0;n=0;do{k=c[3344+(n<<2)>>2]|0;j=c[3408+(n<<2)>>2]|0;e=(j<<4)+k|0;h=f+e|0;j=b+k+(Z(j,p)|0)|0;k=x+j|0;q=c[g+(n<<6)>>2]|0;if((q|0)==16777215){j=c[f+(e+16)>>2]|0;c[k>>2]=c[h>>2];c[k+(o<<2)>>2]=j;j=c[f+(e+48)>>2]|0;c[k+(l<<2)>>2]=c[f+(e+32)>>2];c[k+(m<<2)>>2]=j}else{A=d[f+(e+1)>>0]|0;z=c[g+(n<<6)+4>>2]|0;a[k>>0]=a[3472+(q+512+(d[h>>0]|0))>>0]|0;q=d[f+(e+2)>>0]|0;t=c[g+(n<<6)+8>>2]|0;a[x+(j+1)>>0]=a[3472+((A|512)+z)>>0]|0;k=d[f+(e+3)>>0]|0;h=c[g+(n<<6)+12>>2]|0;a[x+(j+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(j+3)>>0]=a[3472+(h+512+k)>>0]|0;k=j+p|0;h=d[f+(e+17)>>0]|0;j=c[g+(n<<6)+20>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+16>>2]|0)+512+(d[f+(e+16)>>0]|0))>>0]|0;q=d[f+(e+18)>>0]|0;t=c[g+(n<<6)+24>>2]|0;a[x+(k+1)>>0]=a[3472+((h|512)+j)>>0]|0;j=d[f+(e+19)>>0]|0;h=c[g+(n<<6)+28>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(h+512+j)>>0]|0;k=k+p|0;j=d[f+(e+33)>>0]|0;h=c[g+(n<<6)+36>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+32>>2]|0)+512+(d[f+(e+32)>>0]|0))>>0]|0;q=d[f+(e+34)>>0]|0;t=c[g+(n<<6)+40>>2]|0;a[x+(k+1)>>0]=a[3472+((j|512)+h)>>0]|0;h=d[f+(e+35)>>0]|0;j=c[g+(n<<6)+44>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(j+512+h)>>0]|0;k=k+p|0;h=d[f+(e+49)>>0]|0;j=c[g+(n<<6)+52>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+48>>2]|0)+512+(d[f+(e+48)>>0]|0))>>0]|0;q=d[f+(e+50)>>0]|0;t=c[g+(n<<6)+56>>2]|0;a[x+(k+1)>>0]=a[3472+((h|512)+j)>>0]|0;j=d[f+(e+51)>>0]|0;h=c[g+(n<<6)+60>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(h+512+j)>>0]|0}n=n+1|0}while((n|0)!=16);t=s<<6;s=r<<3&2147483640;r=f+256|0;f=f+320|0;l=w+v+(u<<6)|0;p=s>>>2;j=s>>>1;k=j+p|0;o=16;do{q=o&3;h=c[3344+(q<<2)>>2]|0;q=c[3408+(q<<2)>>2]|0;e=o>>>0>19;m=e?f:r;n=(q<<3)+h|0;b=m+n|0;q=l+(e?t:0)+h+(Z(q,s)|0)|0;h=x+q|0;e=c[g+(o<<6)>>2]|0;if((e|0)==16777215){z=c[m+(n+8)>>2]|0;c[h>>2]=c[b>>2];c[h+(p<<2)>>2]=z;z=c[m+(n+24)>>2]|0;c[h+(j<<2)>>2]=c[m+(n+16)>>2];c[h+(k<<2)>>2]=z}else{v=d[m+(n+1)>>0]|0;z=c[g+(o<<6)+4>>2]|0;a[h>>0]=a[3472+(e+512+(d[b>>0]|0))>>0]|0;w=d[m+(n+2)>>0]|0;u=c[g+(o<<6)+8>>2]|0;a[x+(q+1)>>0]=a[3472+((v|512)+z)>>0]|0;z=d[m+(n+3)>>0]|0;v=c[g+(o<<6)+12>>2]|0;a[x+(q+2)>>0]=a[3472+(u+512+w)>>0]|0;a[x+(q+3)>>0]=a[3472+(v+512+z)>>0]|0;z=q+s|0;v=d[m+(n+9)>>0]|0;w=c[g+(o<<6)+20>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+16>>2]|0)+512+(d[m+(n+8)>>0]|0))>>0]|0;u=d[m+(n+10)>>0]|0;q=c[g+(o<<6)+24>>2]|0;a[x+(z+1)>>0]=a[3472+((v|512)+w)>>0]|0;w=d[m+(n+11)>>0]|0;v=c[g+(o<<6)+28>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(v+512+w)>>0]|0;z=z+s|0;w=d[m+(n+17)>>0]|0;v=c[g+(o<<6)+36>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+32>>2]|0)+512+(d[m+(n+16)>>0]|0))>>0]|0;u=d[m+(n+18)>>0]|0;q=c[g+(o<<6)+40>>2]|0;a[x+(z+1)>>0]=a[3472+((w|512)+v)>>0]|0;v=d[m+(n+19)>>0]|0;w=c[g+(o<<6)+44>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(w+512+v)>>0]|0;z=z+s|0;v=d[m+(n+25)>>0]|0;w=c[g+(o<<6)+52>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+48>>2]|0)+512+(d[m+(n+24)>>0]|0))>>0]|0;u=d[m+(n+26)>>0]|0;q=c[g+(o<<6)+56>>2]|0;a[x+(z+1)>>0]=a[3472+((v|512)+w)>>0]|0;w=d[m+(n+27)>>0]|0;v=c[g+(o<<6)+60>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(v+512+w)>>0]|0}o=o+1|0}while((o|0)!=24);i=y;return}function uc(e,f){e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0;bb=i;i=i+176|0;ia=bb+40|0;La=bb;ea=c[e+4>>2]|0;ka=e+8|0;Wa=c[ka>>2]|0;g=Z(Wa,ea)|0;if(!Wa){i=bb;return}Za=ia+24|0;_a=ia+16|0;$a=ia+8|0;la=ia+100|0;ma=ia+68|0;na=ia+36|0;oa=ia+4|0;Ma=ia+120|0;Na=ia+112|0;Pa=ia+104|0;Qa=ia+96|0;Ra=ia+88|0;Sa=ia+80|0;Ta=ia+72|0;Ua=ia+64|0;Va=ia+56|0;Wa=ia+48|0;Xa=ia+40|0;Ya=ia+32|0;pa=ia+124|0;qa=ia+116|0;ra=ia+108|0;sa=ia+92|0;ta=ia+84|0;ua=ia+76|0;va=ia+60|0;wa=ia+52|0;xa=ia+44|0;ya=ia+28|0;za=ia+20|0;Aa=ia+12|0;ha=La+28|0;ja=La+32|0;Ka=La+24|0;Da=ea<<4;Ja=0-Da|0;Ca=Ja<<1;Ha=Z(ea,-48)|0;Ia=ea<<5;Ea=Ja<<2;Ga=ea*48|0;Ba=ea<<6;ga=La+24|0;fa=La+12|0;Fa=g<<8;ba=g<<6;ca=ea<<3;W=Da|4;Y=La+16|0;$=La+20|0;da=La+12|0;X=La+4|0;_=La+8|0;U=0;aa=0;V=f;while(1){f=c[V+8>>2]|0;do if((f|0)!=1){T=V+200|0;n=c[T>>2]|0;do if(!n)g=1;else{if((f|0)==2?(c[V+4>>2]|0)!=(c[n+4>>2]|0):0){g=1;break}g=5}while(0);S=V+204|0;l=c[S>>2]|0;do if(l){if((f|0)==2?(c[V+4>>2]|0)!=(c[l+4>>2]|0):0)break;g=g|2}while(0);R=(g&2|0)==0;do if(R){c[Za>>2]=0;c[_a>>2]=0;c[$a>>2]=0;c[ia>>2]=0;m=0}else{if((c[V>>2]|0)>>>0<=5?(c[l>>2]|0)>>>0<=5:0){if((b[V+28>>1]|0)==0?(b[l+48>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[l+124>>2]|0)?(B=(b[V+132>>1]|0)-(b[l+172>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){h=(b[V+134>>1]|0)-(b[l+174>>1]|0)|0;h=(((h|0)>-1?h:0-h|0)|0)>3&1}else h=1;else h=2;c[ia>>2]=h;if((b[V+30>>1]|0)==0?(b[l+50>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[l+124>>2]|0)?(B=(b[V+136>>1]|0)-(b[l+176>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){j=(b[V+138>>1]|0)-(b[l+178>>1]|0)|0;j=(((j|0)>-1?j:0-j|0)|0)>3&1}else j=1;else j=2;c[$a>>2]=j;if((b[V+36>>1]|0)==0?(b[l+56>>1]|0)==0:0)if((c[V+120>>2]|0)==(c[l+128>>2]|0)?(B=(b[V+148>>1]|0)-(b[l+188>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){k=(b[V+150>>1]|0)-(b[l+190>>1]|0)|0;k=(((k|0)>-1?k:0-k|0)|0)>3&1}else k=1;else k=2;c[_a>>2]=k;if((b[V+38>>1]|0)==0?(b[l+58>>1]|0)==0:0)if((c[V+120>>2]|0)==(c[l+128>>2]|0)?(B=(b[V+152>>1]|0)-(b[l+192>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){f=(b[V+154>>1]|0)-(b[l+194>>1]|0)|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=1;else f=2;c[Za>>2]=f;m=(j|h|k|f|0)!=0&1;break}c[Za>>2]=4;c[_a>>2]=4;c[$a>>2]=4;c[ia>>2]=4;m=1}while(0);Q=(g&4|0)==0;do if(Q){c[la>>2]=0;c[ma>>2]=0;c[na>>2]=0;c[oa>>2]=0;k=c[V>>2]|0}else{k=c[V>>2]|0;if(k>>>0<=5?(c[n>>2]|0)>>>0<=5:0){if((b[V+28>>1]|0)==0?(b[n+38>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[n+120>>2]|0)?(B=(b[V+132>>1]|0)-(b[n+152>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){j=(b[V+134>>1]|0)-(b[n+154>>1]|0)|0;j=(((j|0)>-1?j:0-j|0)|0)>3&1}else j=1;else j=2;c[oa>>2]=j;if((b[V+32>>1]|0)==0?(b[n+42>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[n+120>>2]|0)?(B=(b[V+140>>1]|0)-(b[n+160>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){h=(b[V+142>>1]|0)-(b[n+162>>1]|0)|0;h=(((h|0)>-1?h:0-h|0)|0)>3&1}else h=1;else h=2;c[na>>2]=h;if((b[V+44>>1]|0)==0?(b[n+54>>1]|0)==0:0)if((c[V+124>>2]|0)==(c[n+128>>2]|0)?(B=(b[V+164>>1]|0)-(b[n+184>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){f=(b[V+166>>1]|0)-(b[n+186>>1]|0)|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=1;else f=2;c[ma>>2]=f;if((b[V+48>>1]|0)==0?(b[n+58>>1]|0)==0:0)if((c[V+124>>2]|0)==(c[n+128>>2]|0)?(B=(b[V+172>>1]|0)-(b[n+192>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){l=(b[V+174>>1]|0)-(b[n+194>>1]|0)|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=1;else l=2;c[la>>2]=l;if(m)break;m=(h|j|f|l|0)!=0&1;break}c[la>>2]=4;c[ma>>2]=4;c[na>>2]=4;c[oa>>2]=4;m=1}while(0);if(k>>>0<=5){do if((db(k)|0)!=1){f=c[V>>2]|0;if((f|0)==2){w=V+28|0;x=b[V+32>>1]|0;if(!(x<<16>>16))f=(b[w>>1]|0)!=0?2:0;else f=2;c[Ya>>2]=f;q=b[V+34>>1]|0;A=q<<16>>16==0;if(A)f=(b[V+30>>1]|0)!=0?2:0;else f=2;c[Xa>>2]=f;g=b[V+40>>1]|0;z=g<<16>>16==0;if(z)l=(b[V+36>>1]|0)!=0?2:0;else l=2;c[Wa>>2]=l;v=b[V+42>>1]|0;y=v<<16>>16==0;if(y)l=(b[V+38>>1]|0)!=0?2:0;else l=2;c[Va>>2]=l;h=b[V+48>>1]|0;if(!(h<<16>>16))l=(b[V+44>>1]|0)!=0?2:0;else l=2;c[Qa>>2]=l;k=b[V+50>>1]|0;B=k<<16>>16==0;if(B)l=(b[V+46>>1]|0)!=0?2:0;else l=2;c[Pa>>2]=l;p=b[V+56>>1]|0;f=p<<16>>16==0;if(f)n=(b[V+52>>1]|0)!=0?2:0;else n=2;c[Na>>2]=n;j=(b[V+58>>1]|0)==0;if(j)n=(b[V+54>>1]|0)!=0?2:0;else n=2;c[Ma>>2]=n;r=b[V+44>>1]|0;o=b[V+166>>1]|0;n=b[V+142>>1]|0;do if(!((r|x)<<16>>16)){u=(b[V+164>>1]|0)-(b[V+140>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){n=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){n=1;break}n=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else n=2;while(0);c[Ua>>2]=n;s=b[V+46>>1]|0;o=b[V+170>>1]|0;n=b[V+146>>1]|0;do if(!((s|q)<<16>>16)){u=(b[V+168>>1]|0)-(b[V+144>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[Ta>>2]=o;t=b[V+52>>1]|0;o=b[V+182>>1]|0;n=b[V+158>>1]|0;do if(!((t|g)<<16>>16)){u=(b[V+180>>1]|0)-(b[V+156>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Sa>>2]=o;u=b[V+54>>1]|0;o=b[V+186>>1]|0;n=b[V+162>>1]|0;do if(!((u|v)<<16>>16)){v=(b[V+184>>1]|0)-(b[V+160>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){o=1;break}v=o-n|0;if((((v|0)>-1?v:0-v|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Ra>>2]=o;l=b[V+30>>1]|0;if(!(l<<16>>16))o=(b[w>>1]|0)!=0?2:0;else o=2;c[Aa>>2]=o;n=b[V+36>>1]|0;if(!(n<<16>>16))o=l<<16>>16!=0?2:0;else o=2;c[za>>2]=o;if(!(b[V+38>>1]|0))o=n<<16>>16!=0?2:0;else o=2;c[ya>>2]=o;if(A)n=x<<16>>16!=0?2:0;else n=2;c[xa>>2]=n;if(z)l=q<<16>>16!=0?2:0;else l=2;c[wa>>2]=l;if(y)l=g<<16>>16!=0?2:0;else l=2;c[va>>2]=l;if(!(s<<16>>16))l=r<<16>>16!=0?2:0;else l=2;c[ua>>2]=l;if(!(t<<16>>16))l=s<<16>>16!=0?2:0;else l=2;c[ta>>2]=l;if(!(u<<16>>16))l=t<<16>>16!=0?2:0;else l=2;c[sa>>2]=l;if(B)h=h<<16>>16!=0?2:0;else h=2;c[ra>>2]=h;if(f)f=k<<16>>16!=0?2:0;else f=2;c[qa>>2]=f;if(j)f=p<<16>>16!=0?2:0;else f=2;c[pa>>2]=f;break}else if((f|0)==3){j=V+28|0;v=b[V+32>>1]|0;if(!(v<<16>>16))f=(b[j>>1]|0)!=0?2:0;else f=2;c[Ya>>2]=f;B=b[V+34>>1]|0;p=B<<16>>16==0;if(p)h=(b[V+30>>1]|0)!=0?2:0;else h=2;c[Xa>>2]=h;z=b[V+40>>1]|0;if(!(z<<16>>16))k=(b[V+36>>1]|0)!=0?2:0;else k=2;c[Wa>>2]=k;o=b[V+42>>1]|0;h=o<<16>>16==0;if(h)l=(b[V+38>>1]|0)!=0?2:0;else l=2;c[Va>>2]=l;f=b[V+44>>1]|0;if(!(f<<16>>16))l=v<<16>>16!=0?2:0;else l=2;c[Ua>>2]=l;A=b[V+46>>1]|0;g=A<<16>>16==0;if(g)l=B<<16>>16!=0?2:0;else l=2;c[Ta>>2]=l;y=b[V+52>>1]|0;if(!(y<<16>>16))l=z<<16>>16!=0?2:0;else l=2;c[Sa>>2]=l;k=b[V+54>>1]|0;q=k<<16>>16==0;if(q)l=o<<16>>16!=0?2:0;else l=2;c[Ra>>2]=l;r=b[V+48>>1]|0;if(!(r<<16>>16))n=f<<16>>16!=0?2:0;else n=2;c[Qa>>2]=n;x=b[V+50>>1]|0;s=x<<16>>16==0;if(s)n=A<<16>>16!=0?2:0;else n=2;c[Pa>>2]=n;w=b[V+56>>1]|0;if(!(w<<16>>16))o=y<<16>>16!=0?2:0;else o=2;c[Na>>2]=o;u=(b[V+58>>1]|0)==0;if(u)o=k<<16>>16!=0?2:0;else o=2;c[Ma>>2]=o;t=b[V+30>>1]|0;if(!(t<<16>>16))o=(b[j>>1]|0)!=0?2:0;else o=2;c[Aa>>2]=o;if(!(b[V+38>>1]|0))o=(b[V+36>>1]|0)!=0?2:0;else o=2;c[ya>>2]=o;if(p)n=v<<16>>16!=0?2:0;else n=2;c[xa>>2]=n;if(h)n=z<<16>>16!=0?2:0;else n=2;c[va>>2]=n;if(g)l=f<<16>>16!=0?2:0;else l=2;c[ua>>2]=l;if(q)l=y<<16>>16!=0?2:0;else l=2;c[sa>>2]=l;if(s)l=r<<16>>16!=0?2:0;else l=2;c[ra>>2]=l;if(u)l=w<<16>>16!=0?2:0;else l=2;c[pa>>2]=l;l=b[V+150>>1]|0;k=b[V+138>>1]|0;do if(!((b[V+36>>1]|t)<<16>>16)){v=(b[V+148>>1]|0)-(b[V+136>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){l=1;break}v=l-k|0;if((((v|0)>-1?v:0-v|0)|0)>3){l=1;break}l=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else l=2;while(0);c[za>>2]=l;l=b[V+158>>1]|0;k=b[V+146>>1]|0;do if(!((z|B)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+144>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}B=l-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}k=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else k=2;while(0);c[wa>>2]=k;l=b[V+182>>1]|0;k=b[V+170>>1]|0;do if(!((y|A)<<16>>16)){B=(b[V+180>>1]|0)-(b[V+168>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}B=l-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else f=2;while(0);c[ta>>2]=f;f=b[V+190>>1]|0;g=b[V+178>>1]|0;do if(!((w|x)<<16>>16)){B=(b[V+188>>1]|0)-(b[V+176>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}B=f-g|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else f=2;while(0);c[qa>>2]=f;break}else{K=b[V+32>>1]|0;z=b[V+28>>1]|0;P=b[V+142>>1]|0;q=b[V+134>>1]|0;if(!((z|K)<<16>>16)){B=(b[V+140>>1]|0)-(b[V+132>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)k=1;else{k=P-q|0;k=(((k|0)>-1?k:0-k|0)|0)>3&1}}else k=2;c[Ya>>2]=k;L=b[V+34>>1]|0;y=b[V+30>>1]|0;O=b[V+146>>1]|0;r=b[V+138>>1]|0;if(!((y|L)<<16>>16)){B=(b[V+144>>1]|0)-(b[V+136>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)l=1;else{l=O-r|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}}else l=2;c[Xa>>2]=l;M=b[V+40>>1]|0;x=b[V+36>>1]|0;N=b[V+158>>1]|0;s=b[V+150>>1]|0;if(!((x|M)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+148>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)n=1;else{n=N-s|0;n=(((n|0)>-1?n:0-n|0)|0)>3&1}}else n=2;c[Wa>>2]=n;n=b[V+42>>1]|0;B=b[V+38>>1]|0;J=b[V+162>>1]|0;A=b[V+154>>1]|0;if(!((B|n)<<16>>16)){w=(b[V+160>>1]|0)-(b[V+152>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3)o=1;else{o=J-A|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}}else o=2;c[Va>>2]=o;D=b[V+44>>1]|0;I=b[V+166>>1]|0;do if(!((D|K)<<16>>16)){w=(b[V+164>>1]|0)-(b[V+140>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3)o=1;else{w=I-P|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}}else o=2;while(0);c[Ua>>2]=o;E=b[V+46>>1]|0;H=b[V+170>>1]|0;do if(!((E|L)<<16>>16)){w=(b[V+168>>1]|0)-(b[V+144>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}w=H-O|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[Ta>>2]=o;F=b[V+52>>1]|0;G=b[V+182>>1]|0;do if(!((F|M)<<16>>16)){w=(b[V+180>>1]|0)-(b[V+156>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}w=G-N|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Sa>>2]=o;g=b[V+54>>1]|0;l=b[V+186>>1]|0;do if(!((g|n)<<16>>16)){w=(b[V+184>>1]|0)-(b[V+160>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}w=l-J|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else u=2;while(0);c[Ra>>2]=u;f=b[V+48>>1]|0;C=b[V+174>>1]|0;do if(!((f|D)<<16>>16)){w=(b[V+172>>1]|0)-(b[V+164>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=C-I|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Qa>>2]=u;h=b[V+50>>1]|0;k=b[V+178>>1]|0;do if(!((h|E)<<16>>16)){w=(b[V+176>>1]|0)-(b[V+168>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=k-H|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Pa>>2]=u;j=b[V+56>>1]|0;p=b[V+190>>1]|0;do if(!((j|F)<<16>>16)){w=(b[V+188>>1]|0)-(b[V+180>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=p-G|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Na>>2]=u;w=b[V+58>>1]|0;t=b[V+194>>1]|0;do if(!((w|g)<<16>>16)){v=(b[V+192>>1]|0)-(b[V+184>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){v=1;break}v=t-l|0;v=(((v|0)>-1?v:0-v|0)|0)>3&1}else v=2;while(0);c[Ma>>2]=v;do if(!((y|z)<<16>>16)){z=(b[V+136>>1]|0)-(b[V+132>>1]|0)|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}u=r-q|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Aa>>2]=u;do if(!((x|y)<<16>>16)){z=(b[V+148>>1]|0)-(b[V+136>>1]|0)|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}z=s-r|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}u=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else u=2;while(0);c[za>>2]=u;do if(!((B|x)<<16>>16)){B=(b[V+152>>1]|0)-(b[V+148>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){u=1;break}u=A-s|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[ya>>2]=u;do if(!((L|K)<<16>>16)){B=(b[V+144>>1]|0)-(b[V+140>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=O-P|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}else o=2;while(0);c[xa>>2]=o;do if(!((M|L)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+144>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}B=N-O|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[wa>>2]=o;do if(!((n|M)<<16>>16)){B=(b[V+160>>1]|0)-(b[V+156>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=J-N|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}else o=2;while(0);c[va>>2]=o;do if(!((E|D)<<16>>16)){B=(b[V+168>>1]|0)-(b[V+164>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}n=H-I|0;n=(((n|0)>-1?n:0-n|0)|0)>3&1}else n=2;while(0);c[ua>>2]=n;do if(!((F|E)<<16>>16)){B=(b[V+180>>1]|0)-(b[V+168>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}B=G-H|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}n=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else n=2;while(0);c[ta>>2]=n;do if(!((g|F)<<16>>16)){B=(b[V+184>>1]|0)-(b[V+180>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){l=1;break}l=l-G|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=2;while(0);c[sa>>2]=l;do if(!((h|f)<<16>>16)){B=(b[V+176>>1]|0)-(b[V+172>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){l=1;break}l=k-C|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=2;while(0);c[ra>>2]=l;do if(!((j|h)<<16>>16)){B=(b[V+188>>1]|0)-(b[V+176>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}B=p-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}k=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else k=2;while(0);c[qa>>2]=k;do if(!((w|j)<<16>>16)){B=(b[V+192>>1]|0)-(b[V+188>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=t-p|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=2;while(0);c[pa>>2]=f;break}}else vc(V,ia);while(0);if(!(m|c[Ya>>2]|c[Xa>>2]|c[Wa>>2]|c[Va>>2]|c[Ua>>2]|c[Ta>>2]|c[Sa>>2]|c[Ra>>2]|c[Qa>>2]|c[Pa>>2]|c[Na>>2]|c[Ma>>2]|c[Aa>>2]|c[za>>2]|c[ya>>2]|c[xa>>2]|c[wa>>2]|c[va>>2]|c[ua>>2]|c[ta>>2]|c[sa>>2]|c[ra>>2]|c[qa>>2]|c[pa>>2]))break}else{c[Ma>>2]=3;c[Na>>2]=3;c[Pa>>2]=3;c[Qa>>2]=3;c[Ra>>2]=3;c[Sa>>2]=3;c[Ta>>2]=3;c[Ua>>2]=3;c[Va>>2]=3;c[Wa>>2]=3;c[Xa>>2]=3;c[Ya>>2]=3;c[pa>>2]=3;c[qa>>2]=3;c[ra>>2]=3;c[sa>>2]=3;c[ta>>2]=3;c[ua>>2]=3;c[va>>2]=3;c[wa>>2]=3;c[xa>>2]=3;c[ya>>2]=3;c[za>>2]=3;c[Aa>>2]=3}J=V+20|0;g=c[J>>2]|0;L=V+12|0;k=Oa(0,51,(c[L>>2]|0)+g|0)|0;K=V+16|0;h=Oa(0,51,(c[K>>2]|0)+g|0)|0;j=d[6864+k>>0]|0;c[ha>>2]=j;h=d[6920+h>>0]|0;c[ja>>2]=h;k=6976+(k*3|0)|0;c[Ka>>2]=k;do if(!R){l=c[(c[S>>2]|0)+20>>2]|0;if((l|0)==(g|0)){c[X>>2]=j;c[_>>2]=h;c[La>>2]=k;break}else{A=(g+1+l|0)>>>1;B=Oa(0,51,(c[L>>2]|0)+A|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[X>>2]=d[6864+B>>0];c[_>>2]=d[6920+A>>0];c[La>>2]=6976+(B*3|0);break}}while(0);do if(!Q){f=c[(c[T>>2]|0)+20>>2]|0;if((f|0)==(g|0)){c[Y>>2]=c[ha>>2];c[$>>2]=c[ja>>2];c[da>>2]=c[Ka>>2];break}else{A=(g+1+f|0)>>>1;B=Oa(0,51,(c[L>>2]|0)+A|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[Y>>2]=d[6864+B>>0];c[$>>2]=d[6920+A>>0];c[da>>2]=6976+(B*3|0);break}}while(0);M=Z(aa,ea)|0;P=3;o=0;O=(c[e>>2]|0)+((M<<8)+(U<<4))|0;N=ia;while(1){l=c[N+4>>2]|0;if(l)wc(O,l,fa,Da);l=c[N+12>>2]|0;if(l)wc(O+4|0,l,ga,Da);k=N+16|0;m=c[N+20>>2]|0;if(m)wc(O+8|0,m,ga,Da);j=N+24|0;m=c[N+28>>2]|0;if(m)wc(O+12|0,m,ga,Da);n=c[N>>2]|0;l=N+8|0;m=c[l>>2]|0;a:do if(((n|0)==(m|0)?(n|0)==(c[k>>2]|0):0)?(n|0)==(c[j>>2]|0):0){if(!n)break;y=c[La+(o*12|0)+4>>2]|0;x=c[La+(o*12|0)+8>>2]|0;if(n>>>0<4){t=d[(c[La+(o*12|0)>>2]|0)+(n+-1)>>0]|0;k=0-t|0;j=t+1|0;f=O;h=16;while(1){o=f+Ca|0;s=d[o>>0]|0;u=f+Ja|0;r=d[u>>0]|0;q=d[f>>0]|0;m=f+Da|0;g=d[m>>0]|0;B=r-q|0;do if(((B|0)>-1?B:0-B|0)>>>0>>0){B=s-r|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=g-q|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;n=d[f+Ha>>0]|0;B=n-r|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[o>>0]=(Oa(k,t,((r+1+q|0)>>>1)-(s<<1)+n>>1)|0)+s;o=j}else o=t;n=d[f+Ia>>0]|0;B=n-q|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[m>>0]=(Oa(k,t,((r+1+q|0)>>>1)-(g<<1)+n>>1)|0)+g;o=o+1|0}A=Oa(0-o|0,o,s+4-g+(q-r<<2)>>3)|0;B=a[3472+((q|512)-A)>>0]|0;a[u>>0]=a[3472+(A+(r|512))>>0]|0;a[f>>0]=B}while(0);h=h+-1|0;if(!h)break a;else f=f+1|0}}n=(y>>>2)+2|0;t=O;u=16;while(1){m=t+Ca|0;f=d[m>>0]|0;l=t+Ja|0;g=d[l>>0]|0;p=d[t>>0]|0;k=t+Da|0;q=d[k>>0]|0;o=g-p|0;o=(o|0)>-1?o:0-o|0;b:do if(o>>>0>>0){B=f-g|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=q-p|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;j=t+Ha|0;r=d[j>>0]|0;h=t+Ia|0;s=d[h>>0]|0;do if(o>>>0>>0){B=r-g|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){B=g+f+p|0;a[l>>0]=(q+4+(B<<1)+r|0)>>>3;a[m>>0]=(B+2+r|0)>>>2;a[j>>0]=(B+4+(r*3|0)+(d[t+Ea>>0]<<1)|0)>>>3}else a[l>>0]=(g+2+(f<<1)+q|0)>>>2;B=s-p|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=p+g+q|0;a[t>>0]=(f+4+(B<<1)+s|0)>>>3;a[k>>0]=(B+2+s|0)>>>2;a[h>>0]=(B+4+(s*3|0)+(d[t+Ga>>0]<<1)|0)>>>3;break b}else a[l>>0]=(g+2+(f<<1)+q|0)>>>2;while(0);a[t>>0]=(f+2+p+(q<<1)|0)>>>2}while(0);u=u+-1|0;if(!u)break;else t=t+1|0}}else ab=311;while(0);do if((ab|0)==311){ab=0;if(n){xc(O,n,La+(o*12|0)|0,Da);m=c[l>>2]|0}if(m)xc(O+4|0,m,La+(o*12|0)|0,Da);m=c[k>>2]|0;if(m)xc(O+8|0,m,La+(o*12|0)|0,Da);l=c[j>>2]|0;if(!l)break;xc(O+12|0,l,La+(o*12|0)|0,Da)}while(0);if(!P)break;else{P=P+-1|0;o=2;O=O+Ba|0;N=N+32|0}}h=c[V+24>>2]|0;g=c[192+((Oa(0,51,(c[J>>2]|0)+h|0)|0)<<2)>>2]|0;m=Oa(0,51,(c[L>>2]|0)+g|0)|0;j=Oa(0,51,(c[K>>2]|0)+g|0)|0;k=d[6864+m>>0]|0;c[ha>>2]=k;j=d[6920+j>>0]|0;c[ja>>2]=j;m=6976+(m*3|0)|0;c[Ka>>2]=m;do if(!R){l=c[(c[S>>2]|0)+20>>2]|0;if((l|0)==(c[J>>2]|0)){c[X>>2]=k;c[_>>2]=j;c[La>>2]=m;break}else{A=(g+1+(c[192+((Oa(0,51,l+h|0)|0)<<2)>>2]|0)|0)>>>1;B=Oa(0,51,A+(c[L>>2]|0)|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[X>>2]=d[6864+B>>0];c[_>>2]=d[6920+A>>0];c[La>>2]=6976+(B*3|0);break}}while(0);do if(!Q){f=c[(c[T>>2]|0)+20>>2]|0;if((f|0)==(c[J>>2]|0)){c[Y>>2]=c[ha>>2];c[$>>2]=c[ja>>2];c[da>>2]=c[Ka>>2];break}else{A=(g+1+(c[192+((Oa(0,51,f+h|0)|0)<<2)>>2]|0)|0)>>>1;B=Oa(0,51,A+(c[L>>2]|0)|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[Y>>2]=d[6864+B>>0];c[$>>2]=d[6920+A>>0];c[da>>2]=6976+(B*3|0);break}}while(0);j=c[e>>2]|0;l=(U<<3)+Fa+(M<<6)|0;n=j+l|0;l=j+(l+ba)|0;j=0;h=ia;o=0;while(1){g=h+4|0;f=c[g>>2]|0;if(f){yc(n,f,fa,ca);yc(l,c[g>>2]|0,fa,ca)}g=h+36|0;f=c[g>>2]|0;if(f){yc(n+Da|0,f,fa,ca);yc(l+Da|0,c[g>>2]|0,fa,ca)}m=h+16|0;g=h+20|0;f=c[g>>2]|0;if(f){yc(n+4|0,f,ga,ca);yc(l+4|0,c[g>>2]|0,ga,ca)}g=h+52|0;f=c[g>>2]|0;if(f){yc(n+W|0,f,ga,ca);yc(l+W|0,c[g>>2]|0,ga,ca)}g=c[h>>2]|0;k=h+8|0;f=c[k>>2]|0;do if((g|0)==(f|0)){if((g|0)!=(c[m>>2]|0)){ab=342;break}if((g|0)!=(c[h+24>>2]|0)){ab=342;break}if(!g)break;B=La+(j*12|0)|0;zc(n,g,B,ca);zc(l,c[h>>2]|0,B,ca)}else ab=342;while(0);do if((ab|0)==342){ab=0;if(g){f=La+(j*12|0)|0;Ac(n,g,f,ca);Ac(l,c[h>>2]|0,f,ca);f=c[k>>2]|0}if(f){B=La+(j*12|0)|0;Ac(n+2|0,f,B,ca);Ac(l+2|0,c[k>>2]|0,B,ca)}f=c[m>>2]|0;if(f){B=La+(j*12|0)|0;Ac(n+4|0,f,B,ca);Ac(l+4|0,c[m>>2]|0,B,ca)}g=h+24|0;f=c[g>>2]|0;if(!f)break;B=La+(j*12|0)|0;Ac(n+6|0,f,B,ca);Ac(l+6|0,c[g>>2]|0,B,ca)}while(0);o=o+1|0;if((o|0)==2)break;else{n=n+Ia|0;l=l+Ia|0;j=2;h=h+64|0}}}while(0);f=U+1|0;g=(f|0)==(ea|0);aa=(g&1)+aa|0;if(aa>>>0>=(c[ka>>2]|0)>>>0)break;else{U=g?0:f;V=V+216|0}}i=bb;return}function vc(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;B=i;l=a+28|0;y=b[a+32>>1]|0;if(!(y<<16>>16))e=(b[l>>1]|0)!=0?2:0;else e=2;c[d+32>>2]=e;z=b[a+34>>1]|0;x=z<<16>>16==0;if(x)e=(b[a+30>>1]|0)!=0?2:0;else e=2;c[d+40>>2]=e;A=b[a+40>>1]|0;v=A<<16>>16==0;if(v)e=(b[a+36>>1]|0)!=0?2:0;else e=2;c[d+48>>2]=e;f=b[a+42>>1]|0;w=f<<16>>16==0;if(w)e=(b[a+38>>1]|0)!=0?2:0;else e=2;c[d+56>>2]=e;s=b[a+44>>1]|0;if(!(s<<16>>16))e=y<<16>>16!=0?2:0;else e=2;c[d+64>>2]=e;t=b[a+46>>1]|0;p=t<<16>>16==0;if(p)e=z<<16>>16!=0?2:0;else e=2;c[d+72>>2]=e;u=b[a+52>>1]|0;q=u<<16>>16==0;if(q)e=A<<16>>16!=0?2:0;else e=2;c[d+80>>2]=e;g=b[a+54>>1]|0;r=g<<16>>16==0;if(r)e=f<<16>>16!=0?2:0;else e=2;c[d+88>>2]=e;m=b[a+48>>1]|0;if(!(m<<16>>16))e=s<<16>>16!=0?2:0;else e=2;c[d+96>>2]=e;n=b[a+50>>1]|0;h=n<<16>>16==0;if(h)e=t<<16>>16!=0?2:0;else e=2;c[d+104>>2]=e;o=b[a+56>>1]|0;j=o<<16>>16==0;if(j)f=u<<16>>16!=0?2:0;else f=2;c[d+112>>2]=f;k=(b[a+58>>1]|0)==0;if(k)f=g<<16>>16!=0?2:0;else f=2;c[d+120>>2]=f;g=b[a+30>>1]|0;if(!(g<<16>>16))f=(b[l>>1]|0)!=0?2:0;else f=2;c[d+12>>2]=f;e=b[a+36>>1]|0;if(!(e<<16>>16))f=g<<16>>16!=0?2:0;else f=2;c[d+20>>2]=f;if(!(b[a+38>>1]|0))e=e<<16>>16!=0?2:0;else e=2;c[d+28>>2]=e;if(x)e=y<<16>>16!=0?2:0;else e=2;c[d+44>>2]=e;if(v)e=z<<16>>16!=0?2:0;else e=2;c[d+52>>2]=e;if(w)e=A<<16>>16!=0?2:0;else e=2;c[d+60>>2]=e;if(p)e=s<<16>>16!=0?2:0;else e=2;c[d+76>>2]=e;if(q)e=t<<16>>16!=0?2:0;else e=2;c[d+84>>2]=e;if(r)e=u<<16>>16!=0?2:0;else e=2;c[d+92>>2]=e;if(h)e=m<<16>>16!=0?2:0;else e=2;c[d+108>>2]=e;if(j)e=n<<16>>16!=0?2:0;else e=2;c[d+116>>2]=e;if(!k){y=2;z=d+124|0;c[z>>2]=y;i=B;return}y=o<<16>>16!=0?2:0;z=d+124|0;c[z>>2]=y;i=B;return}function wc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=i;u=c[f+4>>2]|0;v=c[f+8>>2]|0;if(e>>>0<4){l=d[(c[f>>2]|0)+(e+-1)>>0]|0;n=0-l|0;m=l+1|0;k=4;while(1){f=b+-2|0;s=d[f>>0]|0;t=b+-1|0;r=d[t>>0]|0;q=d[b>>0]|0;j=b+1|0;h=d[j>>0]|0;o=r-q|0;if((((o|0)>-1?o:0-o|0)>>>0>>0?(o=s-r|0,((o|0)>-1?o:0-o|0)>>>0>>0):0)?(o=h-q|0,((o|0)>-1?o:0-o|0)>>>0>>0):0){e=d[b+-3>>0]|0;p=d[b+2>>0]|0;o=e-r|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){a[f>>0]=(Oa(n,l,((r+1+q|0)>>>1)-(s<<1)+e>>1)|0)+s;f=m}else f=l;o=p-q|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){a[j>>0]=(Oa(n,l,((r+1+q|0)>>>1)-(h<<1)+p>>1)|0)+h;f=f+1|0}j=Oa(0-f|0,f,s+4-h+(q-r<<2)>>3)|0;o=a[3472+((q|512)-j)>>0]|0;a[t>>0]=a[3472+((r|512)+j)>>0]|0;a[b>>0]=o}k=k+-1|0;if(!k)break;else b=b+g|0}i=w;return}t=(u>>>2)+2|0;s=4;while(1){k=b+-2|0;q=d[k>>0]|0;l=b+-1|0;r=d[l>>0]|0;m=d[b>>0]|0;e=b+1|0;n=d[e>>0]|0;f=r-m|0;f=(f|0)>-1?f:0-f|0;do if((f>>>0>>0?(o=q-r|0,((o|0)>-1?o:0-o|0)>>>0>>0):0)?(o=n-m|0,((o|0)>-1?o:0-o|0)>>>0>>0):0){h=b+-3|0;o=d[h>>0]|0;j=b+2|0;p=d[j>>0]|0;if(f>>>0>>0){f=o-r|0;if(((f|0)>-1?f:0-f|0)>>>0>>0){f=r+q+m|0;a[l>>0]=(n+4+(f<<1)+o|0)>>>3;a[k>>0]=(f+2+o|0)>>>2;a[h>>0]=(f+4+(o*3|0)+((d[b+-4>>0]|0)<<1)|0)>>>3}else a[l>>0]=(r+2+(q<<1)+n|0)>>>2;o=p-m|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){o=m+r+n|0;a[b>>0]=(q+4+(o<<1)+p|0)>>>3;a[e>>0]=(o+2+p|0)>>>2;a[j>>0]=(o+4+(p*3|0)+((d[b+3>>0]|0)<<1)|0)>>>3;break}}else a[l>>0]=(r+2+(q<<1)+n|0)>>>2;a[b>>0]=(q+2+m+(n<<1)|0)>>>2}while(0);s=s+-1|0;if(!s)break;else b=b+g|0}i=w;return}function xc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;A=i;u=d[(c[f>>2]|0)+(e+-1)>>0]|0;w=0-g|0;v=w<<1;t=f+4|0;o=f+8|0;q=Z(g,-3)|0;s=0-u|0;p=u+1|0;r=g<<1;n=4;while(1){e=b+v|0;k=b+w|0;j=b+g|0;f=a[j>>0]|0;l=d[k>>0]|0;m=d[b>>0]|0;h=l-m|0;if((((h|0)>-1?h:0-h|0)>>>0<(c[t>>2]|0)>>>0?(y=d[e>>0]|0,h=y-l|0,x=c[o>>2]|0,((h|0)>-1?h:0-h|0)>>>0>>0):0)?(z=f&255,f=z-m|0,((f|0)>-1?f:0-f|0)>>>0>>0):0){f=d[b+q>>0]|0;h=f-l|0;if(((h|0)>-1?h:0-h|0)>>>0>>0){a[e>>0]=(Oa(s,u,((l+1+m|0)>>>1)-(y<<1)+f>>1)|0)+y;e=c[o>>2]|0;f=p}else{e=x;f=u}h=d[b+r>>0]|0;B=h-m|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[j>>0]=(Oa(s,u,((l+1+m|0)>>>1)-(z<<1)+h>>1)|0)+z;f=f+1|0}f=Oa(0-f|0,f,4-z+(m-l<<2)+y>>3)|0;e=a[3472+((m|512)-f)>>0]|0;a[k>>0]=a[3472+((l|512)+f)>>0]|0;a[b>>0]=e}n=n+-1|0;if(!n)break;else b=b+1|0}i=A;return} +function ya(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+15&-16;return b|0}function za(){return i|0}function Aa(a){a=a|0;i=a}function Ba(a,b){a=a|0;b=b|0;if(!m){m=a;n=b}}function Ca(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Da(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Ea(a){a=a|0;B=a}function Fa(){return B|0}function Ga(a,b,e,f){a=a|0;b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;k=i;g=d[8+b>>0]|0;j=d[64+b>>0]|0;b=c[120+(j*12|0)>>2]<>2]<>2]<>2]=Z(c[a>>2]|0,b)|0;a:do if(!(f&65436)){if(f&98){n=a+4|0;l=Z(c[n>>2]|0,h)|0;j=a+20|0;m=Z(c[j>>2]|0,b)|0;e=a+24|0;g=Z(c[e>>2]|0,h)|0;h=c[a>>2]|0;b=(l>>1)-g|0;g=l+(g>>1)|0;l=m+h+32|0;f=l+g>>6;c[a>>2]=f;m=h-m+32|0;h=m+b>>6;c[n>>2]=h;b=m-b>>6;c[a+8>>2]=b;g=l-g>>6;c[a+12>>2]=g;c[a+48>>2]=f;c[a+32>>2]=f;c[a+16>>2]=f;c[a+52>>2]=h;c[a+36>>2]=h;c[j>>2]=h;c[a+56>>2]=b;c[a+40>>2]=b;c[e>>2]=b;c[a+60>>2]=g;c[a+44>>2]=g;c[a+28>>2]=g;if((f+512|0)>>>0>1023|(h+512|0)>>>0>1023|(b+512|0)>>>0>1023|(g+512|0)>>>0>1023)g=1;else break;i=k;return g|0}g=(c[a>>2]|0)+32>>6;if((g+512|0)>>>0>1023){m=1;i=k;return m|0}else{c[a+60>>2]=g;c[a+56>>2]=g;c[a+52>>2]=g;c[a+48>>2]=g;c[a+44>>2]=g;c[a+40>>2]=g;c[a+36>>2]=g;c[a+32>>2]=g;c[a+28>>2]=g;c[a+24>>2]=g;c[a+20>>2]=g;c[a+16>>2]=g;c[a+12>>2]=g;c[a+8>>2]=g;c[a+4>>2]=g;c[a>>2]=g;break}}else{z=a+4|0;s=a+56|0;w=a+60|0;t=c[w>>2]|0;u=Z(c[z>>2]|0,h)|0;c[s>>2]=Z(c[s>>2]|0,h)|0;c[w>>2]=Z(t,g)|0;w=a+8|0;t=c[w>>2]|0;s=a+16|0;y=Z(c[a+20>>2]|0,b)|0;o=Z(c[s>>2]|0,g)|0;q=a+12|0;p=c[q>>2]|0;f=Z(c[a+32>>2]|0,h)|0;e=Z(c[a+24>>2]|0,h)|0;r=c[a+28>>2]|0;j=Z(c[a+48>>2]|0,g)|0;n=Z(c[a+36>>2]|0,h)|0;l=c[a+44>>2]|0;m=Z(c[a+40>>2]|0,g)|0;g=Z(c[a+52>>2]|0,h)|0;x=c[a>>2]|0;v=y+x|0;y=x-y|0;x=(u>>1)-e|0;u=(e>>1)+u|0;e=u+v|0;c[a>>2]=e;c[z>>2]=x+y;c[w>>2]=y-x;c[q>>2]=v-u;q=Z(h,r+t|0)|0;r=Z(t-r|0,h)|0;h=(o>>1)-j|0;o=(j>>1)+o|0;j=o+q|0;c[s>>2]=j;c[a+20>>2]=h+r;c[a+24>>2]=r-h;c[a+28>>2]=q-o;o=Z(b,l+p|0)|0;b=Z(p-l|0,b)|0;l=(f>>1)-g|0;f=(g>>1)+f|0;h=f+o|0;c[a+32>>2]=h;c[a+36>>2]=l+b;c[a+40>>2]=b-l;c[a+44>>2]=o-f;f=a+56|0;o=c[f>>2]|0;l=o+n|0;o=n-o|0;b=a+60|0;g=c[b>>2]|0;n=(m>>1)-g|0;m=(g>>1)+m|0;g=m+l|0;c[a+48>>2]=g;c[a+52>>2]=n+o;c[f>>2]=o-n;c[b>>2]=l-m;b=j;j=3;while(1){v=(b>>1)-g|0;g=(g>>1)+b|0;w=h+e+32|0;x=w+g>>6;c[a>>2]=x;b=e-h+32|0;y=b+v>>6;c[a+16>>2]=y;b=b-v>>6;c[a+32>>2]=b;g=w-g>>6;c[a+48>>2]=g;if((x+512|0)>>>0>1023|(y+512|0)>>>0>1023){g=1;b=14;break}if((b+512|0)>>>0>1023|(g+512|0)>>>0>1023){g=1;b=14;break}f=a+4|0;if(!j)break a;e=c[f>>2]|0;h=c[a+36>>2]|0;b=c[a+20>>2]|0;g=c[a+52>>2]|0;a=f;j=j+-1|0}if((b|0)==14){i=k;return g|0}}while(0);y=0;i=k;return y|0}function Ha(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;B=i;e=a[64+d>>0]|0;s=a[8+d>>0]|0;D=b+8|0;u=c[D>>2]|0;j=c[b+20>>2]|0;q=b+16|0;y=c[q>>2]|0;r=b+32|0;z=c[r>>2]|0;E=b+12|0;v=c[E>>2]|0;f=c[b+24>>2]|0;m=c[b+28>>2]|0;o=b+48|0;g=c[o>>2]|0;C=c[b+36>>2]|0;A=c[b+40>>2]|0;F=c[b+44>>2]|0;h=c[b+52>>2]|0;p=c[b>>2]|0;l=j+p|0;j=p-j|0;p=b+4|0;x=c[p>>2]|0;t=x-f|0;x=f+x|0;f=x+l|0;c[b>>2]=f;k=t+j|0;c[p>>2]=k;t=j-t|0;c[D>>2]=t;x=l-x|0;c[E>>2]=x;E=m+u|0;m=u-m|0;u=y-g|0;y=g+y|0;g=y+E|0;c[q>>2]=g;l=u+m|0;c[b+20>>2]=l;u=m-u|0;c[b+24>>2]=u;y=E-y|0;c[b+28>>2]=y;E=F+v|0;F=v-F|0;v=z-h|0;z=h+z|0;h=z+E|0;c[b+32>>2]=h;m=v+F|0;c[b+36>>2]=m;v=F-v|0;c[b+40>>2]=v;z=E-z|0;c[b+44>>2]=z;E=b+56|0;F=c[E>>2]|0;D=F+C|0;F=C-F|0;C=b+60|0;j=c[C>>2]|0;w=A-j|0;A=j+A|0;j=A+D|0;c[b+48>>2]=j;n=w+F|0;c[b+52>>2]=n;w=F-w|0;c[E>>2]=w;A=D-A|0;c[C>>2]=A;s=s&255;e=c[120+((e&255)*12|0)>>2]|0;if(d>>>0>11){d=e<>2]=Z(e+s|0,d)|0;c[q>>2]=Z(f+h|0,d)|0;c[r>>2]=Z(h-f|0,d)|0;c[o>>2]=Z(s-e|0,d)|0;r=m+k|0;e=k-m|0;q=l-n|0;s=n+l|0;c[p>>2]=Z(s+r|0,d)|0;c[b+20>>2]=Z(q+e|0,d)|0;c[b+36>>2]=Z(e-q|0,d)|0;c[b+52>>2]=Z(r-s|0,d)|0;s=v+t|0;t=t-v|0;v=u-w|0;w=w+u|0;c[b+8>>2]=Z(w+s|0,d)|0;c[b+24>>2]=Z(v+t|0,d)|0;c[b+40>>2]=Z(t-v|0,d)|0;c[b+56>>2]=Z(s-w|0,d)|0;w=z+x|0;v=x-z|0;x=y-A|0;y=A+y|0;c[b+12>>2]=Z(y+w|0,d)|0;c[b+28>>2]=Z(x+v|0,d)|0;c[b+44>>2]=Z(v-x|0,d)|0;c[b+60>>2]=Z(w-y|0,d)|0;i=B;return}else{C=(d+-6|0)>>>0<6?1:2;d=2-s|0;s=h+f|0;D=f-h|0;h=g-j|0;f=j+g|0;c[b>>2]=(Z(f+s|0,e)|0)+C>>d;c[q>>2]=(Z(h+D|0,e)|0)+C>>d;c[r>>2]=(Z(D-h|0,e)|0)+C>>d;c[o>>2]=(Z(s-f|0,e)|0)+C>>d;r=m+k|0;f=k-m|0;q=l-n|0;s=n+l|0;c[p>>2]=(Z(s+r|0,e)|0)+C>>d;c[b+20>>2]=(Z(q+f|0,e)|0)+C>>d;c[b+36>>2]=(Z(f-q|0,e)|0)+C>>d;c[b+52>>2]=(Z(r-s|0,e)|0)+C>>d;s=v+t|0;t=t-v|0;v=u-w|0;w=w+u|0;c[b+8>>2]=(Z(w+s|0,e)|0)+C>>d;c[b+24>>2]=(Z(v+t|0,e)|0)+C>>d;c[b+40>>2]=(Z(t-v|0,e)|0)+C>>d;c[b+56>>2]=(Z(s-w|0,e)|0)+C>>d;w=z+x|0;v=x-z|0;x=y-A|0;y=A+y|0;c[b+12>>2]=(Z(y+w|0,e)|0)+C>>d;c[b+28>>2]=(Z(x+v|0,e)|0)+C>>d;c[b+44>>2]=(Z(v-x|0,e)|0)+C>>d;c[b+60>>2]=(Z(w-y|0,e)|0)+C>>d;i=B;return}}function Ia(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;e=c[120+((d[64+b>>0]|0)*12|0)>>2]|0;if(b>>>0>5){e=e<<(d[8+b>>0]|0)+-1;b=0}else b=1;k=c[a>>2]|0;g=a+8|0;h=c[g>>2]|0;m=h+k|0;h=k-h|0;k=a+4|0;j=c[k>>2]|0;l=a+12|0;f=c[l>>2]|0;i=j-f|0;j=f+j|0;c[a>>2]=(Z(j+m|0,e)|0)>>b;c[k>>2]=(Z(m-j|0,e)|0)>>b;c[g>>2]=(Z(i+h|0,e)|0)>>b;c[l>>2]=(Z(h-i|0,e)|0)>>b;l=a+16|0;i=c[l>>2]|0;h=a+24|0;g=c[h>>2]|0;k=g+i|0;g=i-g|0;i=a+20|0;j=c[i>>2]|0;a=a+28|0;m=c[a>>2]|0;f=j-m|0;j=m+j|0;c[l>>2]=(Z(j+k|0,e)|0)>>b;c[i>>2]=(Z(k-j|0,e)|0)>>b;c[h>>2]=(Z(f+g|0,e)|0)>>b;c[a>>2]=(Z(g-f|0,e)|0)>>b;return}function Ja(a,b){a=a|0;b=b|0;var c=0,d=0;d=i;b=1<>>1}while((c|0)!=0&(c&a|0)==0);i=d;return b|0}function Ka(a){a=a|0;var b=0,d=0;d=i;b=8-(c[a+8>>2]|0)|0;a=jb(a,b)|0;if((a|0)==-1){a=1;i=d;return a|0}a=(a|0)!=(c[400+(b+-1<<2)>>2]|0)&1;i=d;return a|0}function La(a){a=a|0;var b=0,d=0,e=0,f=0;d=i;f=c[a+12>>2]<<3;e=c[a+16>>2]|0;b=f-e|0;if((f|0)==(e|0)){a=0;i=d;return a|0}if(b>>>0>8){a=1;i=d;return a|0}else{a=((kb(a)|0)>>>(32-b|0)|0)!=(1<>2]|0;do{d=d+1|0;if(d>>>0>=b>>>0)break}while((c[a+(d<<2)>>2]|0)!=(e|0));i=f;return ((d|0)==(b|0)?0:d)|0}function Na(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=c[a+4>>2]|0;f=(b>>>0)%(e>>>0)|0;d=b-f|0;b=Z(c[a+8>>2]|0,e)|0;e=c[a>>2]|0;c[a+12>>2]=e+((d<<8)+(f<<4));d=(f<<3)+(b<<8)+(d<<6)|0;c[a+16>>2]=e+d;c[a+20>>2]=e+(d+(b<<6));return}function Oa(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)>=(a|0))a=(c|0)>(b|0)?b:c;return a|0}function Pa(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=i;a:do if(((e>>>0>3?(a[b>>0]|0)==0:0)?(a[b+1>>0]|0)==0:0)?(h=a[b+2>>0]|0,(h&255)<2):0){b:do if((e|0)!=3){p=-3;q=3;k=b+3|0;j=2;while(1){if(h<<24>>24)if(h<<24>>24==1&j>>>0>1){o=q;h=0;m=0;l=0;break}else j=0;else j=j+1|0;l=q+1|0;if((l|0)==(e|0))break b;h=a[k>>0]|0;p=~q;q=l;k=k+1|0}while(1){r=a[k>>0]|0;n=o+1|0;j=r<<24>>24!=0;l=(j&1^1)+l|0;h=r<<24>>24==3&(l|0)==2?1:h;if(r<<24>>24==1&l>>>0>1){r=14;break}if(j){m=l>>>0>2?1:m;l=0}if((n|0)==(e|0)){r=18;break}else{o=n;k=k+1|0}}if((r|0)==14){n=p+o-l|0;c[f+12>>2]=n;j=q;l=l-(l>>>0<3?l:3)|0;break a}else if((r|0)==18){n=p+e-l|0;c[f+12>>2]=n;j=q;break a}}while(0);c[g>>2]=e;q=1;i=s;return q|0}else r=19;while(0);if((r|0)==19){c[f+12>>2]=e;n=e;h=1;j=0;m=0;l=0}k=b+j|0;c[f>>2]=k;c[f+4>>2]=k;c[f+8>>2]=0;c[f+16>>2]=0;o=f+12|0;c[g>>2]=l+j+n;if(m){q=1;i=s;return q|0}if(!h){q=0;i=s;return q|0}l=c[o>>2]|0;h=k;m=k;j=0;c:while(1){while(1){q=l;l=l+-1|0;if(!q){r=31;break c}k=a[h>>0]|0;if((j|0)!=2)break;if(k<<24>>24!=3){r=29;break}if(!l){h=1;r=32;break c}h=h+1|0;if((d[h>>0]|0)>3){h=1;r=32;break c}else j=0}if((r|0)==29){r=0;if((k&255)<3){h=1;r=32;break}else j=2}a[m>>0]=k;h=h+1|0;m=m+1|0;j=k<<24>>24==0?j+1|0:0}if((r|0)==31){c[o>>2]=m-h+(c[o>>2]|0);q=0;i=s;return q|0}else if((r|0)==32){i=s;return h|0}return 0}function Qa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;i=i+16|0;n=o;id(b,0,92);f=jb(a,8)|0;a:do if((((f|0)!=-1?(c[b>>2]=f,jb(a,1)|0,jb(a,1)|0,(jb(a,1)|0)!=-1):0)?(jb(a,5)|0)!=-1:0)?(e=jb(a,8)|0,(e|0)!=-1):0){m=b+4|0;c[m>>2]=e;f=b+8|0;d=nb(a,f)|0;if(!d)if((c[f>>2]|0)>>>0<=31){d=nb(a,n)|0;if(!d){f=c[n>>2]|0;if(f>>>0<=12){c[b+12>>2]=1<>2]|0;if(f>>>0<=2){c[b+16>>2]=f;b:do if(!f){d=nb(a,n)|0;if(d)break a;f=c[n>>2]|0;if(f>>>0>12){d=1;break a}c[b+20>>2]=1<>2]=(f|0)==1&1;d=ob(a,b+28|0)|0;if(d)break a;d=ob(a,b+32|0)|0;if(d)break a;h=b+36|0;d=nb(a,h)|0;if(d)break a;f=c[h>>2]|0;if(f>>>0>255){d=1;break a}if(!f){c[b+40>>2]=0;break}f=fd(f<<2)|0;g=b+40|0;c[g>>2]=f;if(!f){d=65535;break a}if(c[h>>2]|0){e=0;while(1){d=ob(a,f+(e<<2)|0)|0;e=e+1|0;if(d)break a;if(e>>>0>=(c[h>>2]|0)>>>0)break b;f=c[g>>2]|0}}}while(0);l=b+44|0;d=nb(a,l)|0;if(!d)if((c[l>>2]|0)>>>0<=16?(k=jb(a,1)|0,(k|0)!=-1):0){c[b+48>>2]=(k|0)==1&1;d=nb(a,n)|0;if(!d){e=b+52|0;c[e>>2]=(c[n>>2]|0)+1;d=nb(a,n)|0;if(!d){k=b+56|0;c[k>>2]=(c[n>>2]|0)+1;h=jb(a,1)|0;if((!((h|0)==0|(h|0)==-1)?(jb(a,1)|0)!=-1:0)?(j=jb(a,1)|0,(j|0)!=-1):0){j=(j|0)==1;c[b+60>>2]=j&1;if(j){j=b+64|0;d=nb(a,j)|0;if(d)break;f=b+68|0;d=nb(a,f)|0;if(d)break;h=b+72|0;d=nb(a,h)|0;if(d)break;g=b+76|0;d=nb(a,g)|0;if(d)break;e=c[e>>2]|0;if((c[j>>2]|0)>((e<<3)+~c[f>>2]|0)){d=1;break}f=c[k>>2]|0;if((c[h>>2]|0)>((f<<3)+~c[g>>2]|0)){d=1;break}}else{e=c[e>>2]|0;f=c[k>>2]|0}d=Z(f,e)|0;do switch(c[m>>2]|0){case 11:{f=396;e=345600;g=58;break}case 12:{f=396;e=912384;g=58;break}case 13:{f=396;e=912384;g=58;break}case 20:{f=396;e=912384;g=58;break}case 21:{f=792;e=1824768;g=58;break}case 22:{f=1620;e=3110400;g=58;break}case 30:{f=1620;e=3110400;g=58;break}case 31:{f=3600;e=6912e3;g=58;break}case 32:{f=5120;e=7864320;g=58;break}case 40:{f=8192;e=12582912;g=58;break}case 41:{f=8192;e=12582912;g=58;break}case 42:{f=8704;e=13369344;g=58;break}case 50:{f=22080;e=42393600;g=58;break}case 51:{f=36864;e=70778880;g=58;break}case 10:{f=99;e=152064;g=58;break}default:g=60}while(0);do if((g|0)==58){if(f>>>0>>0){g=60;break}e=(e>>>0)/((d*384|0)>>>0)|0;e=e>>>0<16?e:16;c[n>>2]=e;f=c[l>>2]|0;if(f>>>0>e>>>0){e=f;g=61}}while(0);if((g|0)==60){c[n>>2]=2147483647;e=c[l>>2]|0;g=61}if((g|0)==61)c[n>>2]=e;g=b+88|0;c[g>>2]=e;e=jb(a,1)|0;if((e|0)==-1){d=1;break}n=(e|0)==1;c[b+80>>2]=n&1;do if(n){e=fd(952)|0;f=b+84|0;c[f>>2]=e;if(!e){d=65535;break a}d=Ec(a,e)|0;if(d)break a;d=c[f>>2]|0;if(!(c[d+920>>2]|0))break;e=c[d+948>>2]|0;if((c[d+944>>2]|0)>>>0>e>>>0){d=1;break a}if(e>>>0<(c[l>>2]|0)>>>0){d=1;break a}if(e>>>0>(c[g>>2]|0)>>>0){d=1;break a}c[g>>2]=(e|0)==0?1:e}while(0);Ka(a)|0;d=0}else d=1}}}else d=1}else d=1}}else d=1}}else d=1}else d=1;while(0);i=o;return d|0}function Ra(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;j=i;if((c[a>>2]|0)!=(c[b>>2]|0)){d=1;i=j;return d|0}if((c[a+4>>2]|0)!=(c[b+4>>2]|0)){d=1;i=j;return d|0}if((c[a+12>>2]|0)!=(c[b+12>>2]|0)){d=1;i=j;return d|0}d=c[a+16>>2]|0;if((d|0)!=(c[b+16>>2]|0)){d=1;i=j;return d|0}if((c[a+44>>2]|0)!=(c[b+44>>2]|0)){d=1;i=j;return d|0}if((c[a+48>>2]|0)!=(c[b+48>>2]|0)){d=1;i=j;return d|0}if((c[a+52>>2]|0)!=(c[b+52>>2]|0)){d=1;i=j;return d|0}if((c[a+56>>2]|0)!=(c[b+56>>2]|0)){d=1;i=j;return d|0}h=c[a+60>>2]|0;if((h|0)!=(c[b+60>>2]|0)){d=1;i=j;return d|0}if((c[a+80>>2]|0)!=(c[b+80>>2]|0)){d=1;i=j;return d|0}a:do if(!d){if((c[a+20>>2]|0)!=(c[b+20>>2]|0)){d=1;i=j;return d|0}}else if((d|0)==1){if((c[a+24>>2]|0)!=(c[b+24>>2]|0)){d=1;i=j;return d|0}if((c[a+28>>2]|0)!=(c[b+28>>2]|0)){d=1;i=j;return d|0}if((c[a+32>>2]|0)!=(c[b+32>>2]|0)){d=1;i=j;return d|0}d=c[a+36>>2]|0;if((d|0)!=(c[b+36>>2]|0)){d=1;i=j;return d|0}if(d){e=c[a+40>>2]|0;f=c[b+40>>2]|0;g=0;while(1){if((c[e+(g<<2)>>2]|0)!=(c[f+(g<<2)>>2]|0)){d=1;break}g=g+1|0;if(g>>>0>=d>>>0)break a}i=j;return d|0}}while(0);if(h){if((c[a+64>>2]|0)!=(c[b+64>>2]|0)){d=1;i=j;return d|0}if((c[a+68>>2]|0)!=(c[b+68>>2]|0)){d=1;i=j;return d|0}if((c[a+72>>2]|0)!=(c[b+72>>2]|0)){d=1;i=j;return d|0}if((c[a+76>>2]|0)!=(c[b+76>>2]|0)){d=1;i=j;return d|0}}d=0;i=j;return d|0}function Sa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;i=i+16|0;j=l+4|0;k=l;id(b,0,72);d=nb(a,b)|0;if(d){i=l;return d|0}if((c[b>>2]|0)>>>0>255){d=1;i=l;return d|0}e=b+4|0;d=nb(a,e)|0;if(d){i=l;return d|0}if((c[e>>2]|0)>>>0>31){d=1;i=l;return d|0}if(jb(a,1)|0){d=1;i=l;return d|0}d=jb(a,1)|0;if((d|0)==-1){d=1;i=l;return d|0}c[b+8>>2]=(d|0)==1&1;d=nb(a,j)|0;if(d){i=l;return d|0}d=(c[j>>2]|0)+1|0;h=b+12|0;c[h>>2]=d;if(d>>>0>8){d=1;i=l;return d|0}a:do if(d>>>0>1){d=b+16|0;e=nb(a,d)|0;if(e){d=e;i=l;return d|0}d=c[d>>2]|0;if(d>>>0>6){d=1;i=l;return d|0}switch(d|0){case 5:case 4:case 3:{d=jb(a,1)|0;if((d|0)==-1){d=1;i=l;return d|0}c[b+32>>2]=(d|0)==1&1;d=nb(a,j)|0;if(!d){c[b+36>>2]=(c[j>>2]|0)+1;break a}else{i=l;return d|0}}case 0:{d=fd(c[h>>2]<<2)|0;f=b+20|0;c[f>>2]=d;if(!d){d=65535;i=l;return d|0}if(!(c[h>>2]|0))break a;else e=0;while(1){d=nb(a,j)|0;if(d)break;c[(c[f>>2]|0)+(e<<2)>>2]=(c[j>>2]|0)+1;e=e+1|0;if(e>>>0>=(c[h>>2]|0)>>>0)break a}i=l;return d|0}case 2:{e=b+24|0;c[e>>2]=fd((c[h>>2]<<2)+-4|0)|0;d=fd((c[h>>2]<<2)+-4|0)|0;g=b+28|0;c[g>>2]=d;if((c[e>>2]|0)==0|(d|0)==0){d=65535;i=l;return d|0}if((c[h>>2]|0)==1)break a;else f=0;while(1){d=nb(a,j)|0;if(d){e=46;break}c[(c[e>>2]|0)+(f<<2)>>2]=c[j>>2];d=nb(a,j)|0;if(d){e=46;break}c[(c[g>>2]|0)+(f<<2)>>2]=c[j>>2];f=f+1|0;if(f>>>0>=((c[h>>2]|0)+-1|0)>>>0)break a}if((e|0)==46){i=l;return d|0}break}case 6:{d=nb(a,j)|0;if(d){i=l;return d|0}e=(c[j>>2]|0)+1|0;d=b+40|0;c[d>>2]=e;e=fd(e<<2)|0;g=b+44|0;c[g>>2]=e;if(!e){d=65535;i=l;return d|0}f=c[432+((c[h>>2]|0)+-1<<2)>>2]|0;if(!(c[d>>2]|0))break a;else e=0;while(1){m=jb(a,f)|0;c[(c[g>>2]|0)+(e<<2)>>2]=m;e=e+1|0;if(m>>>0>=(c[h>>2]|0)>>>0){d=1;break}if(e>>>0>=(c[d>>2]|0)>>>0)break a}i=l;return d|0}default:break a}}while(0);d=nb(a,j)|0;if(d){a=d;i=l;return a|0}d=c[j>>2]|0;if(d>>>0>31){a=1;i=l;return a|0}c[b+48>>2]=d+1;d=nb(a,j)|0;if(d){a=d;i=l;return a|0}if((c[j>>2]|0)>>>0>31){a=1;i=l;return a|0}if(jb(a,1)|0){a=1;i=l;return a|0}if((jb(a,2)|0)>>>0>2){a=1;i=l;return a|0}d=ob(a,k)|0;if(d){a=d;i=l;return a|0}d=(c[k>>2]|0)+26|0;if(d>>>0>51){a=1;i=l;return a|0}c[b+52>>2]=d;d=ob(a,k)|0;if(d){a=d;i=l;return a|0}if(((c[k>>2]|0)+26|0)>>>0>51){a=1;i=l;return a|0}d=ob(a,k)|0;if(d){a=d;i=l;return a|0}d=c[k>>2]|0;if((d+12|0)>>>0>24){a=1;i=l;return a|0}c[b+56>>2]=d;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+60>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+64>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+68>>2]=(d|0)==1&1;Ka(a)|0;a=0;i=l;return a|0}function Ta(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=i;i=i+32|0;s=w+20|0;q=w+16|0;o=w+12|0;l=w+8|0;v=w+4|0;t=w;id(b,0,988);u=Z(c[d+56>>2]|0,c[d+52>>2]|0)|0;k=nb(a,v)|0;if(k){f=k;i=w;return f|0}n=c[v>>2]|0;c[b>>2]=n;if(n>>>0>=u>>>0){f=1;i=w;return f|0}k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;m=b+4|0;c[m>>2]=k;if((k|0)==5|(k|0)==0)j=5;else if(!((k|0)==7|(k|0)==2)){f=1;i=w;return f|0}if((j|0)==5){if((c[f>>2]|0)==5){f=1;i=w;return f|0}if(!(c[d+44>>2]|0)){f=1;i=w;return f|0}}k=nb(a,v)|0;if(k){f=k;i=w;return f|0}n=c[v>>2]|0;c[b+8>>2]=n;if((n|0)!=(c[e>>2]|0)){f=1;i=w;return f|0}n=d+12|0;k=c[n>>2]|0;j=0;while(1)if(!(k>>>j))break;else j=j+1|0;k=jb(a,j+-1|0)|0;if((k|0)==-1){f=1;i=w;return f|0}j=(c[f>>2]|0)==5;if(j&(k|0)!=0){f=1;i=w;return f|0}c[b+12>>2]=k;if(j){k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;c[b+16>>2]=k;if(k>>>0>65535){f=1;i=w;return f|0}}g=d+16|0;k=c[g>>2]|0;if(!k){h=d+20|0;k=c[h>>2]|0;j=0;while(1)if(!(k>>>j))break;else j=j+1|0;k=jb(a,j+-1|0)|0;if((k|0)==-1){f=1;i=w;return f|0}j=b+20|0;c[j>>2]=k;do if(c[e+8>>2]|0){k=ob(a,t)|0;if(!k){c[b+24>>2]=c[t>>2];break}else{f=k;i=w;return f|0}}while(0);if((c[f>>2]|0)==5){k=c[j>>2]|0;if(k>>>0>(c[h>>2]|0)>>>1>>>0){f=1;i=w;return f|0}j=c[b+24>>2]|0;if((k|0)!=(((j|0)>0?0:0-j|0)|0)){f=1;i=w;return f|0}}k=c[g>>2]|0}if((k|0)==1?(c[d+24>>2]|0)==0:0){k=ob(a,t)|0;if(k){f=k;i=w;return f|0}k=b+28|0;c[k>>2]=c[t>>2];do if(c[e+8>>2]|0){j=ob(a,t)|0;if(!j){c[b+32>>2]=c[t>>2];break}else{f=j;i=w;return f|0}}while(0);if((c[f>>2]|0)==5?(j=c[k>>2]|0,k=(c[d+32>>2]|0)+j+(c[b+32>>2]|0)|0,(((j|0)<(k|0)?j:k)|0)!=0):0){f=1;i=w;return f|0}}if(c[e+68>>2]|0){k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;c[b+36>>2]=k;if(k>>>0>127){f=1;i=w;return f|0}}k=c[m>>2]|0;if((k|0)==5|(k|0)==0){k=jb(a,1)|0;if((k|0)==-1){f=1;i=w;return f|0}c[b+40>>2]=k;do if(!k){k=c[e+48>>2]|0;if(k>>>0>16){f=1;i=w;return f|0}else{c[b+44>>2]=k;break}}else{k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;if(k>>>0>15){f=1;i=w;return f|0}else{c[b+44>>2]=k+1;break}}while(0);k=c[m>>2]|0}do if((k|0)==5|(k|0)==0){g=c[b+44>>2]|0;j=c[n>>2]|0;k=jb(a,1)|0;if((k|0)==-1){f=1;i=w;return f|0}c[b+68>>2]=k;if(k){h=0;a:while(1){if(h>>>0>g>>>0){r=1;j=110;break}k=nb(a,l)|0;if(k){r=k;j=110;break}k=c[l>>2]|0;if(k>>>0>3){r=1;j=110;break}c[b+(h*12|0)+72>>2]=k;do if(k>>>0<2){k=nb(a,o)|0;if(k){r=k;j=110;break a}k=c[o>>2]|0;if(k>>>0>=j>>>0){r=1;j=110;break a}c[b+(h*12|0)+76>>2]=k+1}else{if((k|0)!=2)break;k=nb(a,o)|0;if(k){r=k;j=110;break a}c[b+(h*12|0)+80>>2]=c[o>>2]}while(0);if((c[l>>2]|0)==3){j=61;break}else h=h+1|0}if((j|0)==61){if(!h)r=1;else break;i=w;return r|0}else if((j|0)==110){i=w;return r|0}}}while(0);do if(c[f+4>>2]|0){n=c[d+44>>2]|0;f=(c[f>>2]|0)==5;k=jb(a,1)|0;j=(k|0)==-1;if(f){if(j){f=1;i=w;return f|0}c[b+276>>2]=k;g=jb(a,1)|0;if((g|0)==-1){f=1;i=w;return f|0}c[b+280>>2]=g;if((n|0)!=0|(g|0)==0)break;else r=1;i=w;return r|0}if(j){f=1;i=w;return f|0}c[b+284>>2]=k;if(k){j=(n<<1)+2|0;h=0;d=0;g=0;l=0;m=0;while(1){if(h>>>0>j>>>0){r=1;j=110;break}k=nb(a,q)|0;if(k){r=k;j=110;break}k=c[q>>2]|0;if(k>>>0>6){r=1;j=110;break}c[b+(h*20|0)+288>>2]=k;if((k&-3|0)==1){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+292>>2]=(c[s>>2]|0)+1;k=c[q>>2]|0}if((k|0)==2){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+296>>2]=c[s>>2];k=c[q>>2]|0}if((k|0)==3|(k|0)==6){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+300>>2]=c[s>>2];k=c[q>>2]|0}if((k|0)==4){k=nb(a,s)|0;if(k){r=k;j=110;break}k=c[s>>2]|0;if(k>>>0>n>>>0){r=1;j=110;break}if(!k)c[b+(h*20|0)+304>>2]=65535;else c[b+(h*20|0)+304>>2]=k+-1;k=c[q>>2]|0;p=g+1|0}else p=g;l=((k|0)==5&1)+l|0;d=((k|0)!=0&k>>>0<4&1)+d|0;m=((k|0)==6&1)+m|0;if(!k){j=90;break}else{h=h+1|0;g=p}}if((j|0)==90){if(p>>>0>1|l>>>0>1|m>>>0>1){f=1;i=w;return f|0}if((d|0)!=0&(l|0)!=0)r=1;else break;i=w;return r|0}else if((j|0)==110){i=w;return r|0}}}while(0);g=ob(a,t)|0;if(g){f=g;i=w;return f|0}f=c[t>>2]|0;c[b+48>>2]=f;f=f+(c[e+52>>2]|0)|0;c[t>>2]=f;if(f>>>0>51){f=1;i=w;return f|0}do if(c[e+60>>2]|0){g=nb(a,v)|0;if(g){f=g;i=w;return f|0}g=c[v>>2]|0;c[b+52>>2]=g;if(g>>>0>2){f=1;i=w;return f|0}if((g|0)==1)break;g=ob(a,t)|0;if(g){f=g;i=w;return f|0}g=c[t>>2]|0;if((g+6|0)>>>0>12){f=1;i=w;return f|0}c[b+56>>2]=g<<1;g=ob(a,t)|0;if(g){f=g;i=w;return f|0}g=c[t>>2]|0;if((g+6|0)>>>0>12){f=1;i=w;return f|0}else{c[b+60>>2]=g<<1;break}}while(0);do if((c[e+12>>2]|0)>>>0>1?((c[e+16>>2]|0)+-3|0)>>>0<3:0){k=e+36|0;j=c[k>>2]|0;j=(((u>>>0)%(j>>>0)|0|0)==0?1:2)+((u>>>0)/(j>>>0)|0)|0;h=0;while(1){g=h+1|0;if(!(-1<>2]=g;if((g|0)==-1){f=1;i=w;return f|0}c[b+64>>2]=g;f=c[k>>2]|0;if(g>>>0>(((u+-1+f|0)>>>0)/(f>>>0)|0)>>>0)r=1;else break;i=w;return r|0}while(0);f=0;i=w;return f|0}function Ua(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;i=i+32|0;e=f+20|0;d=f;c[d+0>>2]=c[a+0>>2];c[d+4>>2]=c[a+4>>2];c[d+8>>2]=c[a+8>>2];c[d+12>>2]=c[a+12>>2];c[d+16>>2]=c[a+16>>2];a=nb(d,e)|0;if(!a){a=nb(d,e)|0;if(!a){a=nb(d,e)|0;if(!a){a=c[e>>2]|0;if(a>>>0>255)a=1;else{c[b>>2]=a;a=0}}}}i=f;return a|0}function Va(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+32|0;e=g+20|0;f=g;c[f+0>>2]=c[a+0>>2];c[f+4>>2]=c[a+4>>2];c[f+8>>2]=c[a+8>>2];c[f+12>>2]=c[a+12>>2];c[f+16>>2]=c[a+16>>2];a=nb(f,e)|0;if(a){i=g;return a|0}a=nb(f,e)|0;if(a){i=g;return a|0}a=nb(f,e)|0;if(!a)a=0;else{i=g;return a|0}while(1)if(!(b>>>a))break;else a=a+1|0;a=jb(f,a+-1|0)|0;if((a|0)==-1){a=1;i=g;return a|0}c[d>>2]=a;a=0;i=g;return a|0}function Wa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;h=i;i=i+32|0;f=h+20|0;g=h;if((d|0)!=5){d=1;i=h;return d|0};c[g+0>>2]=c[a+0>>2];c[g+4>>2]=c[a+4>>2];c[g+8>>2]=c[a+8>>2];c[g+12>>2]=c[a+12>>2];c[g+16>>2]=c[a+16>>2];d=nb(g,f)|0;if(d){i=h;return d|0}d=nb(g,f)|0;if(d){i=h;return d|0}d=nb(g,f)|0;if(!d)d=0;else{i=h;return d|0}while(1)if(!(b>>>d))break;else d=d+1|0;if((jb(g,d+-1|0)|0)==-1){d=1;i=h;return d|0}d=nb(g,e)|0;i=h;return d|0}function Xa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;k=i;i=i+32|0;h=k+20|0;j=k;c[j+0>>2]=c[a+0>>2];c[j+4>>2]=c[a+4>>2];c[j+8>>2]=c[a+8>>2];c[j+12>>2]=c[a+12>>2];c[j+16>>2]=c[a+16>>2];a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=c[b+12>>2]|0;f=0;while(1)if(!(a>>>f))break;else f=f+1|0;if((jb(j,f+-1|0)|0)==-1){f=1;i=k;return f|0}if((d|0)==5?(g=nb(j,h)|0,(g|0)!=0):0){f=g;i=k;return f|0}f=c[b+20>>2]|0;a=0;while(1)if(!(f>>>a))break;else a=a+1|0;f=jb(j,a+-1|0)|0;if((f|0)==-1){f=1;i=k;return f|0}c[e>>2]=f;f=0;i=k;return f|0}function Ya(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;k=i;i=i+32|0;h=k+20|0;j=k;c[j+0>>2]=c[a+0>>2];c[j+4>>2]=c[a+4>>2];c[j+8>>2]=c[a+8>>2];c[j+12>>2]=c[a+12>>2];c[j+16>>2]=c[a+16>>2];a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=c[b+12>>2]|0;f=0;while(1)if(!(a>>>f))break;else f=f+1|0;if((jb(j,f+-1|0)|0)==-1){f=1;i=k;return f|0}if((d|0)==5?(g=nb(j,h)|0,(g|0)!=0):0){f=g;i=k;return f|0}f=c[b+20>>2]|0;a=0;while(1)if(!(f>>>a))break;else a=a+1|0;if((jb(j,a+-1|0)|0)==-1){f=1;i=k;return f|0}f=ob(j,e)|0;i=k;return f|0}function Za(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0;m=i;i=i+32|0;j=m+20|0;l=m;c[l+0>>2]=c[a+0>>2];c[l+4>>2]=c[a+4>>2];c[l+8>>2]=c[a+8>>2];c[l+12>>2]=c[a+12>>2];c[l+16>>2]=c[a+16>>2];g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=c[b+12>>2]|0;a=0;while(1)if(!(g>>>a))break;else a=a+1|0;if((jb(l,a+-1|0)|0)==-1){l=1;i=m;return l|0}if((d|0)==5?(h=nb(l,j)|0,(h|0)!=0):0){l=h;i=m;return l|0}g=ob(l,f)|0;if(g){l=g;i=m;return l|0}if((e|0)!=0?(k=ob(l,f+4|0)|0,(k|0)!=0):0){l=k;i=m;return l|0}l=0;i=m;return l|0}function _a(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;m=i;i=i+32|0;l=m+24|0;j=m+20|0;k=m;c[k+0>>2]=c[b+0>>2];c[k+4>>2]=c[b+4>>2];c[k+8>>2]=c[b+8>>2];c[k+12>>2]=c[b+12>>2];c[k+16>>2]=c[b+16>>2];f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=c[d+12>>2]|0;b=0;while(1)if(!(f>>>b))break;else b=b+1|0;if((jb(k,b+-1|0)|0)==-1){n=1;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}g=d+16|0;f=c[g>>2]|0;if(!f){b=c[d+20>>2]|0;f=0;while(1)if(!(b>>>f))break;else f=f+1|0;if((jb(k,f+-1|0)|0)==-1){n=1;i=m;return n|0}if((c[e+8>>2]|0)!=0?(h=ob(k,j)|0,(h|0)!=0):0){n=h;i=m;return n|0}f=c[g>>2]|0}if((f|0)==1?(c[d+24>>2]|0)==0:0){f=ob(k,j)|0;if(f){n=f;i=m;return n|0}if((c[e+8>>2]|0)!=0?(n=ob(k,j)|0,(n|0)!=0):0){i=m;return n|0}}if((c[e+68>>2]|0)!=0?(o=nb(k,l)|0,(o|0)!=0):0){n=o;i=m;return n|0}n=jb(k,1)|0;c[a>>2]=n;n=(n|0)==-1&1;i=m;return n|0}function $a(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;C=i;i=i+448|0;p=C+8|0;x=C+4|0;v=C;p=p+(0-p&15)|0;n=c[b+3376>>2]|0;j=c[e>>2]|0;c[x>>2]=0;y=b+1192|0;c[y>>2]=(c[y>>2]|0)+1;q=b+1200|0;c[q>>2]=0;o=b+12|0;c[v>>2]=(c[e+48>>2]|0)+(c[(c[o>>2]|0)+52>>2]|0);w=e+36|0;r=b+1212|0;s=e+52|0;t=e+56|0;u=e+60|0;z=e+4|0;l=e+44|0;h=b+1220|0;m=b+1172|0;B=b+1176|0;k=n+12|0;A=0;f=0;while(1){e=c[r>>2]|0;if((c[w>>2]|0)==0?(c[e+(j*216|0)+196>>2]|0)!=0:0){f=1;e=22;break}g=c[(c[o>>2]|0)+56>>2]|0;F=c[s>>2]|0;E=c[t>>2]|0;D=c[u>>2]|0;c[e+(j*216|0)+4>>2]=c[y>>2];c[e+(j*216|0)+8>>2]=F;c[e+(j*216|0)+12>>2]=E;c[e+(j*216|0)+16>>2]=D;c[e+(j*216|0)+24>>2]=g;e=c[z>>2]|0;if((e|0)!=2?!((e|0)==7|(f|0)!=0):0){f=nb(a,x)|0;if(f){e=22;break}e=c[x>>2]|0;if(e>>>0>((c[B>>2]|0)-j|0)>>>0){f=1;e=22;break}if(!e)f=0;else{id(k,0,164);c[n>>2]=0;f=1}}e=c[x>>2]|0;if(!e){f=bb(a,n,(c[r>>2]|0)+(j*216|0)|0,c[z>>2]|0,c[l>>2]|0)|0;if(!f)g=0;else{e=22;break}}else{c[x>>2]=e+-1;g=f}f=gb((c[r>>2]|0)+(j*216|0)|0,n,d,h,v,j,c[(c[o>>2]|0)+64>>2]|0,p)|0;if(f){e=22;break}A=((c[(c[r>>2]|0)+(j*216|0)+196>>2]|0)==1&1)+A|0;if(!(La(a)|0))e=(c[x>>2]|0)!=0;else e=1;f=c[z>>2]|0;if((f|0)==7|(f|0)==2)c[q>>2]=j;j=Ma(c[m>>2]|0,c[B>>2]|0,j)|0;if(!((j|0)!=0|e^1)){f=1;e=22;break}if(!e){e=20;break}else f=g}if((e|0)==20){e=b+1196|0;f=(c[e>>2]|0)+A|0;if(f>>>0>(c[B>>2]|0)>>>0){y=1;i=C;return y|0}c[e>>2]=f;y=0;i=C;return y|0}else if((e|0)==22){i=C;return f|0}return 0}function ab(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;h=c[a+1192>>2]|0;d=c[a+1200>>2]|0;j=a+1212|0;a:do if(!d)d=b;else{e=a+16|0;f=0;do{do{d=d+-1|0;if(d>>>0<=b>>>0)break a}while((c[(c[j>>2]|0)+(d*216|0)+4>>2]|0)!=(h|0));f=f+1|0;g=c[(c[e>>2]|0)+52>>2]|0}while(f>>>0<(g>>>0>10?g:10)>>>0)}while(0);g=a+1172|0;b=a+1176|0;while(1){e=c[j>>2]|0;if((c[e+(d*216|0)+4>>2]|0)!=(h|0)){d=11;break}f=e+(d*216|0)+196|0;e=c[f>>2]|0;if(!e){d=11;break}c[f>>2]=e+-1;d=Ma(c[g>>2]|0,c[b>>2]|0,d)|0;if(!d){d=11;break}}if((d|0)==11){i=k;return}}function bb(a,d,e,f,g){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;B=i;i=i+32|0;u=B+20|0;v=B+16|0;q=B+12|0;p=B+8|0;z=B+4|0;y=B;id(d,0,2088);l=nb(a,z)|0;m=c[z>>2]|0;do if((f|0)==2|(f|0)==7){m=m+6|0;if(m>>>0>31|(l|0)!=0){e=1;i=B;return e|0}else{c[d>>2]=m;o=m;break}}else{m=m+1|0;if(m>>>0>31|(l|0)!=0){e=1;i=B;return e|0}else{c[d>>2]=m;o=m;break}}while(0);a:do if((o|0)!=31){b:do if(o>>>0>=6){o=(o|0)!=6;p=o&1;if(!p){c[v>>2]=0;q=0;while(1){f=kb(a)|0;c[u>>2]=f;t=f>>>31;c[d+(q<<2)+12>>2]=t;if(!t){c[d+(q<<2)+76>>2]=f>>>28&7;m=f<<4;n=1}else{m=f<<1;n=0}f=q|1;t=m>>>31;c[d+(f<<2)+12>>2]=t;if(!t){c[d+(f<<2)+76>>2]=m>>>28&7;l=m<<4;n=n+1|0}else l=m<<1;m=f+1|0;t=l>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=l>>>28&7;m=l<<4;n=n+1|0}else m=l<<1;l=q|3;t=m>>>31;c[d+(l<<2)+12>>2]=t;if(!t){c[d+(l<<2)+76>>2]=m>>>28&7;f=m<<4;n=n+1|0}else f=m<<1;m=l+1|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=l+2|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=l+3|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=q|7;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;m=f<<4;n=n+1|0}else m=f<<1;c[u>>2]=m;if((lb(a,(n*3|0)+8|0)|0)==-1){w=1;t=68;break b}t=(c[v>>2]|0)+1|0;c[v>>2]=t;if((t|0)<2)q=q+8|0;else{t=52;break}}}else if((p|0)==1)t=52;if((t|0)==52){v=(nb(a,u)|0)!=0;l=c[u>>2]|0;if(v|l>>>0>3){w=1;t=68;break}c[d+140>>2]=l}if(o){v=c[d>>2]|0;s=v+-7|0;u=s>>>2;c[d+4>>2]=(s>>>0>11?u+268435453|0:u)<<4|(v>>>0>18?15:0)}else{x=p;t=70}}else{if((o|0)==0|(o|0)==1){r=v;s=u}else if(!((o|0)==3|(o|0)==2)){f=0;do{l=(nb(a,q)|0)!=0;m=c[q>>2]|0;if(l|m>>>0>3){n=1;t=96;break}c[d+(f<<2)+176>>2]=m;f=f+1|0}while(f>>>0<4);if((t|0)==96){i=B;return n|0}c:do if(g>>>0>1&(o|0)!=5){m=g>>>0>2&1;f=0;while(1){if(qb(a,q,m)|0){n=1;t=96;break}n=c[q>>2]|0;if(n>>>0>=g>>>0){n=1;t=96;break}c[d+(f<<2)+192>>2]=n;f=f+1|0;if(f>>>0>=4){h=0;break c}}if((t|0)==96){i=B;return n|0}}else h=0;while(0);d:while(1){n=c[d+(h<<2)+176>>2]|0;if(!n)n=0;else if((n|0)==2|(n|0)==1)n=1;else n=3;c[q>>2]=n;m=0;while(1){n=ob(a,p)|0;if(n){t=96;break d}b[d+(h<<4)+(m<<2)+208>>1]=c[p>>2];n=ob(a,p)|0;if(n){t=96;break d}b[d+(h<<4)+(m<<2)+210>>1]=c[p>>2];t=c[q>>2]|0;c[q>>2]=t+-1;if(!t)break;else m=m+1|0}h=h+1|0;if(h>>>0>=4){x=2;t=70;break b}}if((t|0)==96){i=B;return n|0}}else{r=v;s=u}if(g>>>0>1){if((o|0)==0|(o|0)==1)n=0;else if((o|0)==3|(o|0)==2)n=1;else n=3;l=g>>>0>2&1;f=0;while(1){if(qb(a,u,l)|0){w=1;t=68;break b}m=c[u>>2]|0;if(m>>>0>=g>>>0){w=1;t=68;break b}c[d+(f<<2)+144>>2]=m;if(!n)break;else{n=n+-1|0;f=f+1|0}}}if((o|0)==0|(o|0)==1){l=0;m=0}else if((o|0)==3|(o|0)==2){l=1;m=0}else{l=3;m=0}while(1){f=ob(a,v)|0;if(f){w=f;t=68;break b}b[d+(m<<2)+160>>1]=c[v>>2];f=ob(a,v)|0;if(f){w=f;t=68;break b}b[d+(m<<2)+162>>1]=c[v>>2];if(!l){x=2;t=70;break}else{l=l+-1|0;m=m+1|0}}}while(0);if((t|0)==68){e=w;i=B;return e|0}do if((t|0)==70){h=pb(a,z,(x|0)==0&1)|0;if(!h){z=c[z>>2]|0;c[d+4>>2]=z;if(!z)break a;else break}else{e=h;i=B;return e|0}}while(0);z=(ob(a,y)|0)!=0;h=c[y>>2]|0;if(z|(h|0)<-26|(h|0)>25){e=1;i=B;return e|0}c[d+8>>2]=h;l=c[d+4>>2]|0;o=d+272|0;e:do if((c[d>>2]|0)>>>0>=7){h=rb(a,d+1864|0,ib(e,0,o)|0,16)|0;if(!(h&15)){b[d+320>>1]=h>>>4&255;h=0;m=3;while(1){n=l>>>1;if(!(l&1))h=h+4|0;else{f=3;while(1){l=rb(a,d+(h<<6)+332|0,ib(e,h,o)|0,15)|0;c[d+(h<<2)+1992>>2]=l>>>15;if(l&15){j=l;break e}b[d+(h<<1)+272>>1]=l>>>4&255;h=h+1|0;if(!f)break;else f=f+-1|0}}if(!m){k=h;A=n;t=87;break}else{l=n;m=m+-1|0}}}else j=h}else{h=0;m=3;while(1){n=l>>>1;if(!(l&1))h=h+4|0;else{f=3;while(1){l=rb(a,d+(h<<6)+328|0,ib(e,h,o)|0,16)|0;c[d+(h<<2)+1992>>2]=l>>>16;if(l&15){j=l;break e}b[d+(h<<1)+272>>1]=l>>>4&255;h=h+1|0;if(!f)break;else f=f+-1|0}}if(!m){k=h;A=n;t=87;break}else{l=n;m=m+-1|0}}}while(0);f:do if((t|0)==87){if(A&3){j=rb(a,d+1928|0,-1,4)|0;if(j&15)break;b[d+322>>1]=j>>>4&255;j=rb(a,d+1944|0,-1,4)|0;if(j&15)break;b[d+324>>1]=j>>>4&255}if(!(A&2))j=0;else{h=7;while(1){j=rb(a,d+(k<<6)+332|0,ib(e,k,o)|0,15)|0;if(j&15)break f;b[d+(k<<1)+272>>1]=j>>>4&255;c[d+(k<<2)+1992>>2]=j>>>15;if(!h){j=0;break}else{k=k+1|0;h=h+-1|0}}}}while(0);c[a+16>>2]=((c[a+4>>2]|0)-(c[a>>2]|0)<<3)+(c[a+8>>2]|0);if(j){e=j;i=B;return e|0}}else{while(1){if(mb(a)|0)break;if(jb(a,1)|0){n=1;t=96;break}}if((t|0)==96){i=B;return n|0}k=0;j=d+328|0;while(1){h=jb(a,8)|0;c[z>>2]=h;if((h|0)==-1){n=1;break}c[j>>2]=h;k=k+1|0;if(k>>>0>=384)break a;else j=j+4|0}i=B;return n|0}while(0);e=0;i=B;return e|0}function cb(a){a=a|0;if(a>>>0<6)a=2;else a=(a|0)!=6&1;return a|0}function db(a){a=a|0;var b=0;b=i;if((a|0)==0|(a|0)==1)a=1;else if((a|0)==3|(a|0)==2)a=2;else a=4;i=b;return a|0}function eb(a){a=a|0;var b=0;b=i;if(!a)a=1;else if((a|0)==2|(a|0)==1)a=2;else a=4;i=b;return a|0}function fb(a){a=a|0;return a+1&3|0}function gb(d,e,f,g,h,j,k,l){d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=i;s=c[e>>2]|0;c[d>>2]=s;o=d+196|0;c[o>>2]=(c[o>>2]|0)+1;Na(f,j);if((s|0)==31){m=d+28|0;c[d+20>>2]=0;if((c[o>>2]|0)>>>0>1){b[m>>1]=16;b[d+30>>1]=16;b[d+32>>1]=16;b[d+34>>1]=16;b[d+36>>1]=16;b[d+38>>1]=16;b[d+40>>1]=16;b[d+42>>1]=16;b[d+44>>1]=16;b[d+46>>1]=16;b[d+48>>1]=16;b[d+50>>1]=16;b[d+52>>1]=16;b[d+54>>1]=16;b[d+56>>1]=16;b[d+58>>1]=16;b[d+60>>1]=16;b[d+62>>1]=16;b[d+64>>1]=16;b[d+66>>1]=16;b[d+68>>1]=16;b[d+70>>1]=16;b[d+72>>1]=16;b[d+74>>1]=16;t=0;i=v;return t|0}o=23;h=e+328|0;n=l;while(1){b[m>>1]=16;a[n>>0]=c[h>>2];a[n+1>>0]=c[h+4>>2];a[n+2>>0]=c[h+8>>2];a[n+3>>0]=c[h+12>>2];a[n+4>>0]=c[h+16>>2];a[n+5>>0]=c[h+20>>2];a[n+6>>0]=c[h+24>>2];a[n+7>>0]=c[h+28>>2];a[n+8>>0]=c[h+32>>2];a[n+9>>0]=c[h+36>>2];a[n+10>>0]=c[h+40>>2];a[n+11>>0]=c[h+44>>2];a[n+12>>0]=c[h+48>>2];a[n+13>>0]=c[h+52>>2];a[n+14>>0]=c[h+56>>2];a[n+15>>0]=c[h+60>>2];if(!o)break;else{o=o+-1|0;h=h+64|0;n=n+16|0;m=m+2|0}}sc(f,l);t=0;i=v;return t|0}m=d+28|0;if(s){hd(m,e+272|0,54);n=c[e+8>>2]|0;o=c[h>>2]|0;do if(n){o=o+n|0;c[h>>2]=o;if((o|0)<0){o=o+52|0;c[h>>2]=o;break}if((o|0)>51){o=o+-52|0;c[h>>2]=o}}while(0);r=d+20|0;c[r>>2]=o;n=e+328|0;h=e+1992|0;a:do if((c[d>>2]|0)>>>0<7){q=15;o=m;while(1){if(b[o>>1]|0){if(Ga(n,c[r>>2]|0,0,c[h>>2]|0)|0){m=1;break}}else c[n>>2]=16777215;n=n+64|0;o=o+2|0;h=h+4|0;if(!q)break a;else q=q+-1|0}i=v;return m|0}else{if(!(b[d+76>>1]|0)){q=464;p=15;o=m}else{Ha(e+1864|0,o);q=464;p=15;o=m}while(1){m=c[e+(c[q>>2]<<2)+1864>>2]|0;q=q+4|0;c[n>>2]=m;if((m|0)==0?(b[o>>1]|0)==0:0)c[n>>2]=16777215;else u=18;if((u|0)==18?(u=0,(Ga(n,c[r>>2]|0,1,c[h>>2]|0)|0)!=0):0){m=1;break}n=n+64|0;o=o+2|0;h=h+4|0;if(!p)break a;else p=p+-1|0}i=v;return m|0}while(0);q=c[192+((Oa(0,51,(c[d+24>>2]|0)+(c[r>>2]|0)|0)|0)<<2)>>2]|0;if((b[d+78>>1]|0)==0?(b[d+80>>1]|0)==0:0){p=e+1928|0;m=7}else{p=e+1928|0;Ia(p,q);m=7}while(1){r=c[p>>2]|0;p=p+4|0;c[n>>2]=r;if((r|0)==0?(b[o>>1]|0)==0:0)c[n>>2]=16777215;else u=31;if((u|0)==31?(u=0,(Ga(n,q,1,c[h>>2]|0)|0)!=0):0){m=1;u=39;break}if(!m)break;else{n=n+64|0;h=h+4|0;m=m+-1|0;o=o+2|0}}if((u|0)==39){i=v;return m|0}if(s>>>0>=6){o=Mb(d,e,f,j,k,l)|0;if(o){t=o;i=v;return t|0}}else u=37}else{id(m,0,54);c[d+20>>2]=c[h>>2];u=37}if((u|0)==37?(t=Sb(d,e,g,j,f,l)|0,(t|0)!=0):0){i=v;return t|0}t=0;i=v;return t|0}function hb(a){a=a|0;return a|0}function ib(d,e,f){d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0;k=i;l=vb(e)|0;g=wb(e)|0;h=a[l+4>>0]|0;j=a[g+4>>0]|0;g=(c[g>>2]|0)==4;if((c[l>>2]|0)==4){e=b[f+((h&255)<<1)>>1]|0;if(g){e=e+1+(b[f+((j&255)<<1)>>1]|0)>>1;i=k;return e|0}g=d+204|0;if(!(zb(d,c[g>>2]|0)|0)){i=k;return e|0}e=e+1+(b[(c[g>>2]|0)+((j&255)<<1)+28>>1]|0)>>1;i=k;return e|0}if(g){e=b[f+((j&255)<<1)>>1]|0;g=d+200|0;if(!(zb(d,c[g>>2]|0)|0)){i=k;return e|0}e=e+1+(b[(c[g>>2]|0)+((h&255)<<1)+28>>1]|0)>>1;i=k;return e|0}g=d+200|0;if(!(zb(d,c[g>>2]|0)|0)){h=0;f=0}else{h=b[(c[g>>2]|0)+((h&255)<<1)+28>>1]|0;f=1}g=d+204|0;if(!(zb(d,c[g>>2]|0)|0)){e=h;i=k;return e|0}e=b[(c[g>>2]|0)+((j&255)<<1)+28>>1]|0;if(!f){i=k;return e|0}e=h+1+e>>1;i=k;return e|0}function jb(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;n=a+4|0;j=c[n>>2]|0;m=c[a+12>>2]<<3;o=a+16|0;l=c[o>>2]|0;g=m-l|0;if((g|0)>31){e=a+8|0;g=c[e>>2]|0;f=(d[j+1>>0]|0)<<16|(d[j>>0]|0)<<24|(d[j+2>>0]|0)<<8|(d[j+3>>0]|0);if(!g)h=e;else{h=e;f=(d[j+4>>0]|0)>>>(8-g|0)|f<0){e=c[h>>2]|0;k=e+24|0;f=(d[j>>0]|0)<0){e=g;g=k;do{j=j+1|0;g=g+-8|0;f=(d[j>>0]|0)<0)}}else f=0}e=l+b|0;c[o>>2]=e;c[h>>2]=e&7;if(e>>>0>m>>>0){n=-1;i=p;return n|0}c[n>>2]=(c[a>>2]|0)+(e>>>3);n=f>>>(32-b|0);i=p;return n|0}function kb(a){a=a|0;var b=0,e=0,f=0,g=0,h=0;g=i;f=c[a+4>>2]|0;e=(c[a+12>>2]<<3)-(c[a+16>>2]|0)|0;if((e|0)>31){b=c[a+8>>2]|0;a=(d[f+1>>0]|0)<<16|(d[f>>0]|0)<<24|(d[f+2>>0]|0)<<8|(d[f+3>>0]|0);if(!b){b=a;i=g;return b|0}b=(d[f+4>>0]|0)>>>(8-b|0)|a<>2]|0;a=h+24|0;b=(d[f>>0]|0)<>0]|0)<0);i=g;return b|0}function lb(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;e=a+16|0;b=(c[e>>2]|0)+b|0;c[e>>2]=b;c[a+8>>2]=b&7;if(b>>>0>c[a+12>>2]<<3>>>0){b=-1;i=d;return b|0}c[a+4>>2]=(c[a>>2]|0)+(b>>>3);b=0;i=d;return b|0}function mb(a){a=a|0;return (c[a+8>>2]|0)==0|0}function nb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=i;d=kb(a)|0;do if((d|0)>=0){if(d>>>0>1073741823){if((lb(a,3)|0)==-1){d=1;break}c[b>>2]=(d>>>29&1)+1;d=0;break}if(d>>>0>536870911){if((lb(a,5)|0)==-1){d=1;break}c[b>>2]=(d>>>27&3)+3;d=0;break}if(d>>>0>268435455){if((lb(a,7)|0)==-1){d=1;break}c[b>>2]=(d>>>25&7)+7;d=0;break}d=Ja(d,28)|0;e=d+4|0;if((e|0)!=32){lb(a,d+5|0)|0;d=jb(a,e)|0;if((d|0)==-1){d=1;break}c[b>>2]=(1<>2]=0;lb(a,32)|0;if((jb(a,1)|0)==1?(f=kb(a)|0,(lb(a,32)|0)!=-1):0)if((f|0)==1){c[b>>2]=-1;d=1;break}else if(!f){c[b>>2]=-1;d=0;break}else{d=1;break}else d=1}else{lb(a,1)|0;c[b>>2]=0;d=0}while(0);i=g;return d|0}function ob(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;f=e;c[f>>2]=0;d=nb(a,f)|0;a=c[f>>2]|0;d=(d|0)==0;if((a|0)==-1)if(d)a=1;else{c[b>>2]=-2147483648;a=0}else if(d){d=(a+1|0)>>>1;c[b>>2]=(a&1|0)!=0?d:0-d|0;a=0}else a=1;i=e;return a|0}function pb(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0;g=i;i=i+16|0;f=g;if(nb(a,f)|0){f=1;i=g;return f|0}f=c[f>>2]|0;if(f>>>0>47){f=1;i=g;return f|0}c[b>>2]=d[((e|0)==0?576:528)+f>>0];f=0;i=g;return f|0}function qb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=i;if(!d){d=jb(a,1)|0;c[b>>2]=d;if((d|0)==-1)d=1;else{c[b>>2]=d^1;d=0}}else d=nb(a,b)|0;i=e;return d|0}function rb(a,b,f,g){a=a|0;b=b|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0;O=i;i=i+128|0;M=O+64|0;N=O;n=kb(a)|0;p=n>>>16;do if(f>>>0<2)if((n|0)>=0){if(n>>>0>201326591){o=e[1264+(n>>>26<<1)>>1]|0;k=25;break}if(n>>>0>16777215){o=e[1328+(n>>>22<<1)>>1]|0;k=25;break}if(n>>>0>2097151){o=e[1424+((n>>>18)+-8<<1)>>1]|0;k=25;break}else{o=e[1536+(p<<1)>>1]|0;k=25;break}}else q=1;else if(f>>>0<4){if((n|0)<0){q=(p&16384|0)!=0?2:2082;break}if(n>>>0>268435455){o=e[1600+(n>>>26<<1)>>1]|0;k=25;break}if(n>>>0>33554431){o=e[1664+(n>>>23<<1)>>1]|0;k=25;break}else{o=e[1728+(n>>>18<<1)>>1]|0;k=25;break}}else{if(f>>>0<8){f=n>>>26;if((f+-8|0)>>>0<56){o=e[1984+(f<<1)>>1]|0;k=25;break}o=e[2112+(n>>>22<<1)>>1]|0;k=25;break}if(f>>>0<17){o=e[2368+(n>>>26<<1)>>1]|0;k=25;break}f=n>>>29;if(f){o=e[2496+(f<<1)>>1]|0;k=25;break}o=e[2512+(n>>>24<<1)>>1]|0;k=25;break}while(0);if((k|0)==25)if(!o){C=1;i=O;return C|0}else q=o;o=q&31;f=n<>>11&31;if(I>>>0>g>>>0){C=1;i=O;return C|0}v=q>>>5&63;do if(I){if(!v)o=0;else{do if(p>>>0>>0)if((lb(a,o)|0)==-1){C=1;i=O;return C|0}else{p=32;f=kb(a)|0;break}while(0);n=f>>>(32-v|0);f=f<>2]=(o&n|0)!=0?-1:1;o=o>>>1;k=k+1|0}while((o|0)!=0);p=p-v|0;o=k}u=v>>>0<3;a:do if(o>>>0>>0){t=o;s=I>>>0>10&u&1;b:while(1){if(p>>>0<16){if((lb(a,32-p|0)|0)==-1){J=1;k=127;break}r=32;f=kb(a)|0}else r=p;do if((f|0)>=0)if(f>>>0<=1073741823)if(f>>>0<=536870911)if(f>>>0<=268435455)if(f>>>0<=134217727)if(f>>>0<=67108863)if(f>>>0<=33554431)if(f>>>0<=16777215)if(f>>>0<=8388607)if(f>>>0>4194303){H=9;k=59}else{if(f>>>0>2097151){H=10;k=59;break}if(f>>>0>1048575){H=11;k=59;break}if(f>>>0>524287){H=12;k=59;break}if(f>>>0>262143){H=13;k=59;break}if(f>>>0>131071){p=14;o=f<<15;n=r+-15|0;q=s;k=(s|0)!=0?s:4}else{if(f>>>0<65536){J=1;k=127;break b}p=15;o=f<<16;n=r+-16|0;q=(s|0)!=0?s:1;k=12}G=p<>>0>>0){if((lb(a,32-y|0)|0)==-1){J=1;k=127;break}o=32;f=kb(a)|0}else{o=y;f=B}E=o-x|0;F=f<>>(32-x|0))+G|0;C=z;D=w}s=(t|0)==(v|0)&u?A+2|0:A;o=(s+2|0)>>>1;n=D?1:C;c[M+(t<<2)>>2]=(s&1|0)==0?o:0-o|0;t=t+1|0;if(t>>>0>=I>>>0){l=E;m=F;break a}else{p=E;f=F;s=((o|0)>(3<>>0<6&1)+n|0}}if((k|0)==127){i=O;return J|0}}else{l=p;m=f}while(0);if(I>>>0>>0){do if(l>>>0<9)if((lb(a,32-l|0)|0)==-1){C=1;i=O;return C|0}else{l=32;m=kb(a)|0;break}while(0);k=m>>>23;c:do if((g|0)==4)if((m|0)>=0)if((I|0)!=3)if(m>>>0<=1073741823)if((I|0)==2)k=34;else k=m>>>0>536870911?35:51;else k=18;else k=17;else k=1;else{do switch(I|0){case 8:{k=d[1056+(m>>>26)>>0]|0;break}case 9:{k=d[1120+(m>>>26)>>0]|0;break}case 2:{k=d[736+(m>>>26)>>0]|0;break}case 1:{if(m>>>0>268435455)k=d[672+(m>>>27)>>0]|0;else k=d[704+k>>0]|0;break}case 13:{k=d[1248+(m>>>29)>>0]|0;break}case 14:{k=d[1256+(m>>>30)>>0]|0;break}case 3:{k=d[800+(m>>>26)>>0]|0;break}case 4:{k=d[864+(m>>>27)>>0]|0;break}case 5:{k=d[896+(m>>>27)>>0]|0;break}case 10:{k=d[1184+(m>>>27)>>0]|0;break}case 6:{k=d[928+(m>>>26)>>0]|0;break}case 7:{k=d[992+(m>>>26)>>0]|0;break}case 11:{k=d[1216+(m>>>28)>>0]|0;break}case 12:{k=d[1232+(m>>>28)>>0]|0;break}default:{k=m>>31&16|1;break c}}while(0);if(!k){C=1;i=O;return C|0}}while(0);n=k&15;l=l-n|0;m=m<>>4&15}else n=0;p=I+-1|0;f=(p|0)==0;if(f){c[b+(n<<2)>>2]=c[M+(p<<2)>>2];K=l;h=1<>2]=1;L=l;j=0}else{if(l>>>0<11){if((lb(a,32-l|0)|0)==-1){J=1;k=127;break}l=32;k=kb(a)|0}switch(n|0){case 4:{m=d[648+(k>>>29)>>0]|0;break}case 5:{m=d[656+(k>>>29)>>0]|0;break}case 6:{m=d[664+(k>>>29)>>0]|0;break}case 1:{m=d[624+(k>>>31)>>0]|0;break}case 2:{m=d[632+(k>>>30)>>0]|0;break}case 3:{m=d[640+(k>>>30)>>0]|0;break}default:{do if(k>>>0<=536870911)if(k>>>0<=268435455)if(k>>>0<=134217727)if(k>>>0<=67108863)if(k>>>0<=33554431)if(k>>>0>16777215)m=184;else{if(k>>>0>8388607){m=201;break}if(k>>>0>4194303){m=218;break}m=k>>>0<2097152?0:235}else m=167;else m=150;else m=133;else m=116;else m=k>>>29<<4^115;while(0);if((m>>>4&15)>>>0>n>>>0){J=1;k=127;break d}}}if(!m){J=1;k=127;break}C=m&15;j=m>>>4&15;c[N+(o<<2)>>2]=j+1;L=l-C|0;k=k<>>0>=p>>>0){k=122;break}else{l=L;n=j}}if((k|0)==122){c[b+(j<<2)>>2]=c[M+(p<<2)>>2];h=1<>2]|0)+j|0;h=1<>2]=c[M+(k<<2)>>2];if(!k){K=L;break}else k=k+-1|0}}else if((k|0)==127){i=O;return J|0}}else{K=p;h=0}while(0);if(lb(a,32-K|0)|0){C=1;i=O;return C|0}C=h<<16|I<<4;i=O;return C|0}function sb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;a:do if((jb(a,1)|0)!=-1?(e=b+4|0,c[e>>2]=jb(a,2)|0,d=jb(a,5)|0,c[b>>2]=d,(d+-2|0)>>>0>=3):0){switch(d|0){case 6:case 9:case 10:case 11:case 12:{if(c[e>>2]|0){d=1;break a}break}case 5:case 7:case 8:{if(!(c[e>>2]|0)){d=1;break a}switch(d|0){case 6:case 9:case 10:case 11:case 12:{d=1;break a}default:{}}break}default:{}}d=0}else d=1;while(0);i=f;return d|0}function tb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;if(!d){i=o;return}m=b+-1|0;j=1-b|0;k=~b;g=0;h=0;l=0;while(1){f=(g|0)!=0;if(f)c[a+(h*216|0)+200>>2]=a+((h+-1|0)*216|0);else c[a+(h*216|0)+200>>2]=0;e=(l|0)!=0;if(e){c[a+(h*216|0)+204>>2]=a+((h-b|0)*216|0);if(g>>>0>>0)c[a+(h*216|0)+208>>2]=a+((j+h|0)*216|0);else n=10}else{c[a+(h*216|0)+204>>2]=0;n=10}if((n|0)==10){n=0;c[a+(h*216|0)+208>>2]=0}if(e&f)c[a+(h*216|0)+212>>2]=a+((h+k|0)*216|0);else c[a+(h*216|0)+212>>2]=0;e=g+1|0;f=(e|0)==(b|0);h=h+1|0;if((h|0)==(d|0))break;else{g=f?0:e;l=(f&1)+l|0}}i=o;return}function ub(a,b){a=a|0;b=b|0;var d=0;d=i;switch(b|0){case 1:{a=c[a+204>>2]|0;break}case 3:{a=c[a+212>>2]|0;break}case 4:break;case 2:{a=c[a+208>>2]|0;break}case 0:{a=c[a+200>>2]|0;break}default:a=0}i=d;return a|0}function vb(a){a=a|0;return 3152+(a<<3)|0}function wb(a){a=a|0;return 2960+(a<<3)|0}function xb(a){a=a|0;return 2768+(a<<3)|0}function yb(a){a=a|0;return 2576+(a<<3)|0}function zb(a,b){a=a|0;b=b|0;var d=0;d=i;if(!b){i=d;return 0}else{i=d;return (c[a+4>>2]|0)==(c[b+4>>2]|0)|0}return 0}function Ab(a){a=a|0;var b=0;b=i;id(a,0,3388);c[a+8>>2]=32;c[a+4>>2]=256;c[a+1332>>2]=1;i=b;return}function Bb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;f=c[b+8>>2]|0;g=a+(f<<2)+20|0;e=c[g>>2]|0;do if(!e){d=fd(92)|0;c[g>>2]=d;if(!d){d=65535;i=h;return d|0}}else{d=a+8|0;if((f|0)!=(c[d>>2]|0)){gd(c[e+40>>2]|0);c[(c[g>>2]|0)+40>>2]=0;gd(c[(c[g>>2]|0)+84>>2]|0);c[(c[g>>2]|0)+84>>2]=0;break}f=a+16|0;if(Ra(b,c[f>>2]|0)|0){gd(c[(c[g>>2]|0)+40>>2]|0);c[(c[g>>2]|0)+40>>2]=0;gd(c[(c[g>>2]|0)+84>>2]|0);c[(c[g>>2]|0)+84>>2]=0;c[d>>2]=33;c[a+4>>2]=257;c[f>>2]=0;c[a+12>>2]=0;break}d=b+40|0;gd(c[d>>2]|0);c[d>>2]=0;d=b+84|0;gd(c[d>>2]|0);c[d>>2]=0;d=0;i=h;return d|0}while(0);f=(c[g>>2]|0)+0|0;d=b+0|0;e=f+92|0;do{c[f>>2]=c[d>>2];f=f+4|0;d=d+4|0}while((f|0)<(e|0));d=0;i=h;return d|0}function Cb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;f=c[b>>2]|0;g=a+(f<<2)+148|0;d=c[g>>2]|0;do if(!d){d=fd(72)|0;c[g>>2]=d;if(!d){d=65535;i=h;return d|0}}else{e=a+4|0;if((f|0)!=(c[e>>2]|0)){gd(c[d+20>>2]|0);c[(c[g>>2]|0)+20>>2]=0;gd(c[(c[g>>2]|0)+24>>2]|0);c[(c[g>>2]|0)+24>>2]=0;gd(c[(c[g>>2]|0)+28>>2]|0);c[(c[g>>2]|0)+28>>2]=0;gd(c[(c[g>>2]|0)+44>>2]|0);c[(c[g>>2]|0)+44>>2]=0;break}if((c[b+4>>2]|0)!=(c[a+8>>2]|0)){c[e>>2]=257;d=c[g>>2]|0}gd(c[d+20>>2]|0);c[(c[g>>2]|0)+20>>2]=0;gd(c[(c[g>>2]|0)+24>>2]|0);c[(c[g>>2]|0)+24>>2]=0;gd(c[(c[g>>2]|0)+28>>2]|0);c[(c[g>>2]|0)+28>>2]=0;gd(c[(c[g>>2]|0)+44>>2]|0);c[(c[g>>2]|0)+44>>2]=0}while(0);f=(c[g>>2]|0)+0|0;d=b+0|0;e=f+72|0;do{c[f>>2]=c[d>>2];f=f+4|0;d=d+4|0}while((f|0)<(e|0));d=0;i=h;return d|0}function Db(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;o=a+(b<<2)+148|0;f=c[o>>2]|0;if(!f){o=1;i=q;return o|0}n=c[f+4>>2]|0;g=c[a+(n<<2)+20>>2]|0;if(!g){o=1;i=q;return o|0}l=c[g+52>>2]|0;m=Z(c[g+56>>2]|0,l)|0;h=c[f+12>>2]|0;a:do if(h>>>0>1){g=c[f+16>>2]|0;if((g|0)==2){k=c[f+24>>2]|0;j=c[f+28>>2]|0;h=h+-1|0;e=0;while(1){f=c[k+(e<<2)>>2]|0;g=c[j+(e<<2)>>2]|0;if(!(f>>>0<=g>>>0&g>>>0>>0)){e=1;g=33;break}e=e+1|0;if(((f>>>0)%(l>>>0)|0)>>>0>((g>>>0)%(l>>>0)|0)>>>0){e=1;g=33;break}if(e>>>0>=h>>>0)break a}if((g|0)==33){i=q;return e|0}}else if(!g){g=c[f+20>>2]|0;f=0;while(1){if((c[g+(f<<2)>>2]|0)>>>0>m>>>0){e=1;break}f=f+1|0;if(f>>>0>=h>>>0)break a}i=q;return e|0}else{if((g+-3|0)>>>0<3){if((c[f+36>>2]|0)>>>0>m>>>0)e=1;else break;i=q;return e|0}if((g|0)!=6)break;if((c[f+40>>2]|0)>>>0>>0)e=1;else break;i=q;return e|0}}while(0);f=a+4|0;g=c[f>>2]|0;do if((g|0)!=256){e=a+3380|0;if(!(c[e>>2]|0)){if((g|0)==(b|0))break;g=a+8|0;if((n|0)==(c[g>>2]|0)){c[f>>2]=b;c[a+12>>2]=c[o>>2];break}if(!d){o=1;i=q;return o|0}else{c[f>>2]=b;o=c[o>>2]|0;c[a+12>>2]=o;o=c[o+4>>2]|0;c[g>>2]=o;o=c[a+(o<<2)+20>>2]|0;c[a+16>>2]=o;n=c[o+52>>2]|0;o=c[o+56>>2]|0;c[a+1176>>2]=Z(o,n)|0;c[a+1340>>2]=n;c[a+1344>>2]=o;c[e>>2]=1;break}}c[e>>2]=0;e=a+1212|0;gd(c[e>>2]|0);c[e>>2]=0;f=a+1172|0;gd(c[f>>2]|0);c[f>>2]=0;g=a+1176|0;c[e>>2]=fd((c[g>>2]|0)*216|0)|0;o=fd(c[g>>2]<<2)|0;c[f>>2]=o;f=c[e>>2]|0;if((f|0)==0|(o|0)==0){o=65535;i=q;return o|0}id(f,0,(c[g>>2]|0)*216|0);f=a+16|0;tb(c[e>>2]|0,c[(c[f>>2]|0)+52>>2]|0,c[g>>2]|0);f=c[f>>2]|0;do if((c[a+1216>>2]|0)==0?(c[f+16>>2]|0)!=2:0){if(((c[f+80>>2]|0)!=0?(p=c[f+84>>2]|0,(c[p+920>>2]|0)!=0):0)?(c[p+944>>2]|0)==0:0){e=1;break}e=0}else e=1;while(0);o=Z(c[f+56>>2]|0,c[f+52>>2]|0)|0;e=lc(a+1220|0,o,c[f+88>>2]|0,c[f+44>>2]|0,c[f+12>>2]|0,e)|0;if(e){o=e;i=q;return o|0}}else{c[f>>2]=b;o=c[o>>2]|0;c[a+12>>2]=o;o=c[o+4>>2]|0;c[a+8>>2]=o;o=c[a+(o<<2)+20>>2]|0;c[a+16>>2]=o;n=c[o+52>>2]|0;o=c[o+56>>2]|0;c[a+1176>>2]=Z(o,n)|0;c[a+1340>>2]=n;c[a+1344>>2]=o;c[a+3380>>2]=1}while(0);o=0;i=q;return o|0}function Eb(a){a=a|0;var b=0,d=0,e=0;e=i;c[a+1196>>2]=0;c[a+1192>>2]=0;d=c[a+1176>>2]|0;if(!d){i=e;return}a=c[a+1212>>2]|0;b=0;do{c[a+(b*216|0)+4>>2]=0;c[a+(b*216|0)+196>>2]=0;b=b+1|0}while(b>>>0>>0);i=e;return}function Fb(a){a=a|0;return (c[a+1188>>2]|0)==0|0}function Gb(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;if(!(c[a+1404>>2]|0)){if((c[a+1196>>2]|0)==(c[a+1176>>2]|0)){a=1;i=f;return a|0}}else{e=c[a+1176>>2]|0;if(!e){a=1;i=f;return a|0}a=c[a+1212>>2]|0;b=0;d=0;do{d=((c[a+(b*216|0)+196>>2]|0)!=0&1)+d|0;b=b+1|0}while(b>>>0>>0);if((d|0)==(e|0)){a=1;i=f;return a|0}}a=0;i=f;return a|0}function Hb(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;e=c[a+16>>2]|0;Kb(c[a+1172>>2]|0,c[a+12>>2]|0,b,c[e+52>>2]|0,c[e+56>>2]|0);i=d;return}function Ib(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;i=i+32|0;g=t+24|0;j=t+20|0;k=t+16|0;n=t+12|0;r=t+8|0;q=t;c[e>>2]=0;switch(c[b>>2]|0){case 5:case 1:{s=d+1300|0;h=d+1332|0;if(c[h>>2]|0){c[e>>2]=1;c[h>>2]=0}h=Ua(a,g)|0;if(h){o=h;i=t;return o|0}l=c[d+(c[g>>2]<<2)+148>>2]|0;if(!l){o=65520;i=t;return o|0}h=c[l+4>>2]|0;m=c[d+(h<<2)+20>>2]|0;if(!m){o=65520;i=t;return o|0}g=c[d+8>>2]|0;if(!((g|0)==32|(h|0)==(g|0))?(c[b>>2]|0)!=5:0){o=65520;i=t;return o|0}g=c[d+1304>>2]|0;h=c[b+4>>2]|0;if((g|0)!=(h|0)?(g|0)==0|(h|0)==0:0)c[e>>2]=1;h=(c[b>>2]|0)==5;if((c[s>>2]|0)==5){if(!h)f=16}else if(h)f=16;if((f|0)==16)c[e>>2]=1;g=m+12|0;if(Va(a,c[g>>2]|0,j)|0){o=1;i=t;return o|0}f=d+1308|0;h=c[j>>2]|0;if((c[f>>2]|0)!=(h|0)){c[f>>2]=h;c[e>>2]=1}if((c[b>>2]|0)==5){if(Wa(a,c[g>>2]|0,5,k)|0){o=1;i=t;return o|0}if((c[s>>2]|0)==5){h=d+1312|0;f=c[h>>2]|0;g=c[k>>2]|0;if((f|0)==(g|0))g=f;else c[e>>2]=1}else{g=c[k>>2]|0;h=d+1312|0}c[h>>2]=g}g=c[m+16>>2]|0;if((g|0)==1){if(!(c[m+24>>2]|0)){h=l+8|0;g=Za(a,m,c[b>>2]|0,c[h>>2]|0,q)|0;if(g){o=g;i=t;return o|0}f=d+1324|0;g=c[q>>2]|0;if((c[f>>2]|0)!=(g|0)){c[f>>2]=g;c[e>>2]=1}if((c[h>>2]|0)!=0?(p=d+1328|0,o=c[q+4>>2]|0,(c[p>>2]|0)!=(o|0)):0){c[p>>2]=o;c[e>>2]=1}}}else if(!g){if(Xa(a,m,c[b>>2]|0,n)|0){o=1;i=t;return o|0}f=d+1316|0;g=c[n>>2]|0;if((c[f>>2]|0)!=(g|0)){c[f>>2]=g;c[e>>2]=1}if(c[l+8>>2]|0){f=Ya(a,m,c[b>>2]|0,r)|0;if(f){o=f;i=t;return o|0}g=d+1320|0;f=c[r>>2]|0;if((c[g>>2]|0)!=(f|0)){c[g>>2]=f;c[e>>2]=1}}}n=b;a=c[n+4>>2]|0;o=s;c[o>>2]=c[n>>2];c[o+4>>2]=a;o=0;i=t;return o|0}case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 16:case 17:case 18:{c[e>>2]=1;o=0;i=t;return o|0}default:{o=0;i=t;return o|0}}return 0}function Jb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;n=i;l=0;a:while(1){b=c[a+(l<<2)+148>>2]|0;b:do if((b|0)!=0?(k=c[a+(c[b+4>>2]<<2)+20>>2]|0,(k|0)!=0):0){j=c[k+52>>2]|0;m=Z(c[k+56>>2]|0,j)|0;f=c[b+12>>2]|0;if(f>>>0<=1){b=0;d=18;break a}d=c[b+16>>2]|0;if((d|0)==2){h=c[b+24>>2]|0;g=c[b+28>>2]|0;f=f+-1|0;e=0;while(1){b=c[h+(e<<2)>>2]|0;d=c[g+(e<<2)>>2]|0;if(!(b>>>0<=d>>>0&d>>>0>>0))break b;e=e+1|0;if(((b>>>0)%(j>>>0)|0)>>>0>((d>>>0)%(j>>>0)|0)>>>0)break b;if(e>>>0>=f>>>0){b=0;d=18;break a}}}else if(d){if((d+-3|0)>>>0<3)if((c[b+36>>2]|0)>>>0>m>>>0)break;else{b=0;d=18;break a}if((d|0)!=6){b=0;d=18;break a}if((c[b+40>>2]|0)>>>0>>0)break;else{b=0;d=18;break a}}else{d=c[b+20>>2]|0;b=0;while(1){if((c[d+(b<<2)>>2]|0)>>>0>m>>>0)break b;b=b+1|0;if(b>>>0>=f>>>0){b=0;d=18;break a}}}}while(0);l=l+1|0;if(l>>>0>=256){b=1;d=18;break}}if((d|0)==18){i=n;return b|0}return 0}function Kb(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=i;t=Z(f,e)|0;o=c[b+12>>2]|0;if((o|0)==1){id(a,0,t<<2);i=v;return}k=c[b+16>>2]|0;if((k+-3|0)>>>0<3){d=Z(c[b+36>>2]|0,d)|0;d=d>>>0>>0?d:t;if((k&-2|0)==4){n=(c[b+32>>2]|0)==0?d:t-d|0;u=d}else{n=0;u=d}}else{n=0;u=0}switch(k|0){case 0:{l=c[b+20>>2]|0;if(!t){i=v;return}else{h=0;j=0}while(1){while(1)if(h>>>0>>0)break;else h=0;b=l+(h<<2)|0;d=c[b>>2]|0;a:do if(!d)d=0;else{k=0;do{g=k+j|0;if(g>>>0>=t>>>0)break a;c[a+(g<<2)>>2]=h;k=k+1|0;d=c[b>>2]|0}while(k>>>0>>0)}while(0);j=d+j|0;if(j>>>0>=t>>>0)break;else h=h+1|0}i=v;return}case 4:{h=c[b+32>>2]|0;if(!t){i=v;return}d=1-h|0;g=0;do{c[a+(g<<2)>>2]=g>>>0>>0?h:d;g=g+1|0}while((g|0)!=(t|0));i=v;return}case 1:{if(!t){i=v;return}else h=0;do{c[a+(h<<2)>>2]=((((Z((h>>>0)/(e>>>0)|0,o)|0)>>>1)+((h>>>0)%(e>>>0)|0)|0)>>>0)%(o>>>0)|0;h=h+1|0}while((h|0)!=(t|0));i=v;return}case 2:{n=c[b+24>>2]|0;m=c[b+28>>2]|0;h=o+-1|0;if(t){d=0;do{c[a+(d<<2)>>2]=h;d=d+1|0}while((d|0)!=(t|0))}if(!h){i=v;return}g=o+-2|0;while(1){j=c[n+(g<<2)>>2]|0;d=(j>>>0)/(e>>>0)|0;j=(j>>>0)%(e>>>0)|0;h=c[m+(g<<2)>>2]|0;l=(h>>>0)/(e>>>0)|0;h=(h>>>0)%(e>>>0)|0;b:do if(d>>>0<=l>>>0){if(j>>>0>h>>>0)while(1){d=d+1|0;if(d>>>0>l>>>0)break b}do{k=Z(d,e)|0;b=j;do{c[a+(b+k<<2)>>2]=g;b=b+1|0}while(b>>>0<=h>>>0);d=d+1|0}while(d>>>0<=l>>>0)}while(0);if(!g)break;else g=g+-1|0}i=v;return}case 5:{d=c[b+32>>2]|0;if(!e){i=v;return}k=1-d|0;if(!f){i=v;return}else{g=0;j=0}while(1){h=0;b=j;while(1){m=a+((Z(h,e)|0)+g<<2)|0;c[m>>2]=b>>>0>>0?d:k;h=h+1|0;if((h|0)==(f|0))break;else b=b+1|0}g=g+1|0;if((g|0)==(e|0))break;else j=j+f|0}i=v;return}case 3:{m=c[b+32>>2]|0;if(t){d=0;do{c[a+(d<<2)>>2]=1;d=d+1|0}while((d|0)!=(t|0))}l=(e-m|0)>>>1;n=(f-m|0)>>>1;if(!u){i=v;return}t=m<<1;r=t+-1|0;s=e+-1|0;t=1-t|0;q=f+-1|0;o=n;p=0;g=l;f=l;k=n;b=l;j=m+-1|0;d=n;while(1){n=a+((Z(d,e)|0)+b<<2)|0;l=(c[n>>2]|0)==1;h=l&1;if(l)c[n>>2]=0;do if(!((j|0)==-1&(b|0)==(g|0))){if((j|0)==1&(b|0)==(f|0)){b=f+1|0;b=(b|0)<(s|0)?b:s;n=o;l=g;f=b;j=0;m=t;break}if((m|0)==-1&(d|0)==(k|0)){d=k+-1|0;d=(d|0)>0?d:0;n=o;l=g;k=d;j=t;m=0;break}if((m|0)==1&(d|0)==(o|0)){d=o+1|0;d=(d|0)<(q|0)?d:q;n=d;l=g;j=r;m=0;break}else{n=o;l=g;b=b+j|0;d=d+m|0;break}}else{b=g+-1|0;b=(b|0)>0?b:0;n=o;l=b;j=0;m=r}while(0);p=h+p|0;if(p>>>0>=u>>>0)break;else{o=n;g=l}}i=v;return}default:{if(!t){i=v;return}g=c[b+44>>2]|0;h=0;do{c[a+(h<<2)>>2]=c[g+(h<<2)>>2];h=h+1|0}while((h|0)!=(t|0));i=v;return}}}function Lb(){return 3472}function Mb(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0;k=i;i=i+80|0;h=k+32|0;j=k;Nb(d,h,j,e);if((cb(c[a>>2]|0)|0)==1){e=Ob(a,g,b+328|0,h,j,f)|0;if(e){i=k;return e|0}}else{e=Pb(a,g,b,h,j,f)|0;if(e){i=k;return e|0}}e=Qb(a,g+256|0,b+1352|0,h+21|0,j+16|0,c[b+140>>2]|0,f)|0;if(e){i=k;return e|0}if((c[a+196>>2]|0)>>>0>1){e=0;i=k;return e|0}sc(d,g);e=0;i=k;return e|0}function Nb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=i;if(!f){i=s;return}p=c[b+4>>2]|0;q=Z(c[b+8>>2]|0,p)|0;n=(f>>>0)/(p>>>0)|0;g=Z(n,p)|0;o=f-g|0;k=p<<4;h=c[b>>2]|0;j=(o<<4)+(Z(p<<8,n)|0)|0;r=(n|0)!=0;if(r){m=j-(k|1)|0;a[d>>0]=a[h+m>>0]|0;a[d+1>>0]=a[h+(m+1)>>0]|0;a[d+2>>0]=a[h+(m+2)>>0]|0;a[d+3>>0]=a[h+(m+3)>>0]|0;a[d+4>>0]=a[h+(m+4)>>0]|0;a[d+5>>0]=a[h+(m+5)>>0]|0;a[d+6>>0]=a[h+(m+6)>>0]|0;a[d+7>>0]=a[h+(m+7)>>0]|0;a[d+8>>0]=a[h+(m+8)>>0]|0;a[d+9>>0]=a[h+(m+9)>>0]|0;a[d+10>>0]=a[h+(m+10)>>0]|0;a[d+11>>0]=a[h+(m+11)>>0]|0;a[d+12>>0]=a[h+(m+12)>>0]|0;a[d+13>>0]=a[h+(m+13)>>0]|0;a[d+14>>0]=a[h+(m+14)>>0]|0;a[d+15>>0]=a[h+(m+15)>>0]|0;a[d+16>>0]=a[h+(m+16)>>0]|0;a[d+17>>0]=a[h+(m+17)>>0]|0;a[d+18>>0]=a[h+(m+18)>>0]|0;a[d+19>>0]=a[h+(m+19)>>0]|0;a[d+20>>0]=a[h+(m+20)>>0]|0;m=d+21|0}else m=d;l=(g|0)!=(f|0);if(l){j=j+-1|0;a[e>>0]=a[h+j>>0]|0;j=j+k|0;a[e+1>>0]=a[h+j>>0]|0;j=j+k|0;a[e+2>>0]=a[h+j>>0]|0;j=j+k|0;a[e+3>>0]=a[h+j>>0]|0;j=j+k|0;a[e+4>>0]=a[h+j>>0]|0;j=j+k|0;a[e+5>>0]=a[h+j>>0]|0;j=j+k|0;a[e+6>>0]=a[h+j>>0]|0;j=j+k|0;a[e+7>>0]=a[h+j>>0]|0;j=j+k|0;a[e+8>>0]=a[h+j>>0]|0;j=j+k|0;a[e+9>>0]=a[h+j>>0]|0;j=j+k|0;a[e+10>>0]=a[h+j>>0]|0;j=j+k|0;a[e+11>>0]=a[h+j>>0]|0;j=j+k|0;a[e+12>>0]=a[h+j>>0]|0;j=j+k|0;a[e+13>>0]=a[h+j>>0]|0;j=j+k|0;a[e+14>>0]=a[h+j>>0]|0;a[e+15>>0]=a[h+(j+k)>>0]|0;e=e+16|0}d=p<<3&2147483640;f=c[b>>2]|0;g=(Z(n<<3,d)|0)+(q<<8)+(o<<3)|0;if(r){b=g-(d|1)|0;a[m>>0]=a[f+b>>0]|0;a[m+1>>0]=a[f+(b+1)>>0]|0;a[m+2>>0]=a[f+(b+2)>>0]|0;a[m+3>>0]=a[f+(b+3)>>0]|0;a[m+4>>0]=a[f+(b+4)>>0]|0;a[m+5>>0]=a[f+(b+5)>>0]|0;a[m+6>>0]=a[f+(b+6)>>0]|0;a[m+7>>0]=a[f+(b+7)>>0]|0;a[m+8>>0]=a[f+(b+8)>>0]|0;b=b+(q<<6)|0;a[m+9>>0]=a[f+b>>0]|0;a[m+10>>0]=a[f+(b+1)>>0]|0;a[m+11>>0]=a[f+(b+2)>>0]|0;a[m+12>>0]=a[f+(b+3)>>0]|0;a[m+13>>0]=a[f+(b+4)>>0]|0;a[m+14>>0]=a[f+(b+5)>>0]|0;a[m+15>>0]=a[f+(b+6)>>0]|0;a[m+16>>0]=a[f+(b+7)>>0]|0;a[m+17>>0]=a[f+(b+8)>>0]|0}if(!l){i=s;return}m=g+-1|0;a[e>>0]=a[f+m>>0]|0;m=m+d|0;a[e+1>>0]=a[f+m>>0]|0;m=m+d|0;a[e+2>>0]=a[f+m>>0]|0;m=m+d|0;a[e+3>>0]=a[f+m>>0]|0;m=m+d|0;a[e+4>>0]=a[f+m>>0]|0;m=m+d|0;a[e+5>>0]=a[f+m>>0]|0;m=m+d|0;a[e+6>>0]=a[f+m>>0]|0;m=m+d|0;a[e+7>>0]=a[f+m>>0]|0;m=m+(d+((q<<6)-(p<<6)))|0;a[e+8>>0]=a[f+m>>0]|0;m=m+d|0;a[e+9>>0]=a[f+m>>0]|0;m=m+d|0;a[e+10>>0]=a[f+m>>0]|0;m=m+d|0;a[e+11>>0]=a[f+m>>0]|0;m=m+d|0;a[e+12>>0]=a[f+m>>0]|0;m=m+d|0;a[e+13>>0]=a[f+m>>0]|0;m=m+d|0;a[e+14>>0]=a[f+m>>0]|0;a[e+15>>0]=a[f+(m+d)>>0]|0;i=s;return}function Ob(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;z=i;k=b+200|0;l=zb(b,c[k>>2]|0)|0;o=(j|0)!=0;if((l|0)!=0&o){n=(cb(c[c[k>>2]>>2]|0)|0)==2;n=n?0:l}else n=l;j=b+204|0;l=zb(b,c[j>>2]|0)|0;if((l|0)!=0&o){p=(cb(c[c[j>>2]>>2]|0)|0)==2;p=p?0:l}else p=l;j=b+212|0;l=zb(b,c[j>>2]|0)|0;if((l|0)!=0&o){r=(cb(c[c[j>>2]>>2]|0)|0)==2;l=r?0:l}j=fb(c[b>>2]|0)|0;if(!j){if(!p){r=1;i=z;return r|0}b=g+1|0;m=g+2|0;s=g+3|0;t=g+4|0;u=g+5|0;v=g+6|0;w=g+7|0;x=g+8|0;y=g+9|0;h=g+10|0;l=g+11|0;j=g+12|0;k=g+13|0;q=g+14|0;r=g+15|0;p=g+16|0;o=e;n=0;while(1){a[o>>0]=a[b>>0]|0;a[o+1>>0]=a[m>>0]|0;a[o+2>>0]=a[s>>0]|0;a[o+3>>0]=a[t>>0]|0;a[o+4>>0]=a[u>>0]|0;a[o+5>>0]=a[v>>0]|0;a[o+6>>0]=a[w>>0]|0;a[o+7>>0]=a[x>>0]|0;a[o+8>>0]=a[y>>0]|0;a[o+9>>0]=a[h>>0]|0;a[o+10>>0]=a[l>>0]|0;a[o+11>>0]=a[j>>0]|0;a[o+12>>0]=a[k>>0]|0;a[o+13>>0]=a[q>>0]|0;a[o+14>>0]=a[r>>0]|0;a[o+15>>0]=a[p>>0]|0;n=n+1|0;if((n|0)==16)break;else o=o+16|0}}else if((j|0)==2){l=g+1|0;k=(n|0)!=0;j=(p|0)!=0;do if(!(k&j)){if(k){k=((d[h>>0]|0)+8+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)+(d[h+4>>0]|0)+(d[h+5>>0]|0)+(d[h+6>>0]|0)+(d[h+7>>0]|0)+(d[h+8>>0]|0)+(d[h+9>>0]|0)+(d[h+10>>0]|0)+(d[h+11>>0]|0)+(d[h+12>>0]|0)+(d[h+13>>0]|0)+(d[h+14>>0]|0)+(d[h+15>>0]|0)|0)>>>4;break}if(j)k=((d[l>>0]|0)+8+(d[g+2>>0]|0)+(d[g+3>>0]|0)+(d[g+4>>0]|0)+(d[g+5>>0]|0)+(d[g+6>>0]|0)+(d[g+7>>0]|0)+(d[g+8>>0]|0)+(d[g+9>>0]|0)+(d[g+10>>0]|0)+(d[g+11>>0]|0)+(d[g+12>>0]|0)+(d[g+13>>0]|0)+(d[g+14>>0]|0)+(d[g+15>>0]|0)+(d[g+16>>0]|0)|0)>>>4;else k=128}else{j=0;k=0;do{r=j;j=j+1|0;k=(d[g+j>>0]|0)+k+(d[h+r>>0]|0)|0}while((j|0)!=16);k=(k+16|0)>>>5}while(0);nd(e|0,k&255|0,256)|0}else if((j|0)==1)if(!n){r=1;i=z;return r|0}else{k=e;j=0;while(1){r=h+j|0;a[k>>0]=a[r>>0]|0;a[k+1>>0]=a[r>>0]|0;a[k+2>>0]=a[r>>0]|0;a[k+3>>0]=a[r>>0]|0;a[k+4>>0]=a[r>>0]|0;a[k+5>>0]=a[r>>0]|0;a[k+6>>0]=a[r>>0]|0;a[k+7>>0]=a[r>>0]|0;a[k+8>>0]=a[r>>0]|0;a[k+9>>0]=a[r>>0]|0;a[k+10>>0]=a[r>>0]|0;a[k+11>>0]=a[r>>0]|0;a[k+12>>0]=a[r>>0]|0;a[k+13>>0]=a[r>>0]|0;a[k+14>>0]=a[r>>0]|0;a[k+15>>0]=a[r>>0]|0;j=j+1|0;if((j|0)==16)break;else k=k+16|0}}else{if(!((n|0)!=0&(p|0)!=0&(l|0)!=0)){r=1;i=z;return r|0}j=d[g+16>>0]|0;m=d[h+15>>0]|0;o=d[g>>0]|0;p=(((d[g+9>>0]|0)-(d[g+7>>0]|0)+((d[g+10>>0]|0)-(d[g+6>>0]|0)<<1)+(((d[g+11>>0]|0)-(d[g+5>>0]|0)|0)*3|0)+((d[g+12>>0]|0)-(d[g+4>>0]|0)<<2)+(((d[g+13>>0]|0)-(d[g+3>>0]|0)|0)*5|0)+(((d[g+14>>0]|0)-(d[g+2>>0]|0)|0)*6|0)+(((d[g+15>>0]|0)-(d[g+1>>0]|0)|0)*7|0)+(j-o<<3)|0)*5|0)+32>>6;o=(((d[h+8>>0]|0)-(d[h+6>>0]|0)+(m-o<<3)+((d[h+9>>0]|0)-(d[h+5>>0]|0)<<1)+(((d[h+10>>0]|0)-(d[h+4>>0]|0)|0)*3|0)+((d[h+11>>0]|0)-(d[h+3>>0]|0)<<2)+(((d[h+12>>0]|0)-(d[h+2>>0]|0)|0)*5|0)+(((d[h+13>>0]|0)-(d[h+1>>0]|0)|0)*6|0)+(((d[h+14>>0]|0)-(d[h>>0]|0)|0)*7|0)|0)*5|0)+32>>6;j=(m+j<<4)+16|0;m=0;do{k=j+(Z(m+-7|0,o)|0)|0;n=m<<4;b=0;do{l=k+(Z(b+-7|0,p)|0)>>5;if((l|0)<0)l=0;else l=(l|0)>255?-1:l&255;a[e+(b+n)>>0]=l;b=b+1|0}while((b|0)!=16);m=m+1|0}while((m|0)!=16)}Rb(e,f,0);Rb(e,f+64|0,1);Rb(e,f+128|0,2);Rb(e,f+192|0,3);Rb(e,f+256|0,4);Rb(e,f+320|0,5);Rb(e,f+384|0,6);Rb(e,f+448|0,7);Rb(e,f+512|0,8);Rb(e,f+576|0,9);Rb(e,f+640|0,10);Rb(e,f+704|0,11);Rb(e,f+768|0,12);Rb(e,f+832|0,13);Rb(e,f+896|0,14);Rb(e,f+960|0,15);r=0;i=z;return r|0}function Pb(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0;N=i;M=(j|0)!=0;L=0;a:while(1){l=vb(L)|0;n=c[l+4>>2]|0;l=ub(b,c[l>>2]|0)|0;j=zb(b,l)|0;if((j|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;j=E?0:j}o=wb(L)|0;m=c[o+4>>2]|0;o=ub(b,c[o>>2]|0)|0;k=zb(b,o)|0;if((k|0)!=0&M){E=(cb(c[o>>2]|0)|0)==2;k=E?0:k}G=(j|0)!=0;H=(k|0)!=0;I=G&H;if(I){if(!(cb(c[l>>2]|0)|0))n=d[l+(n&255)+82>>0]|0;else n=2;if(!(cb(c[o>>2]|0)|0))j=d[o+(m&255)+82>>0]|0;else j=2;j=n>>>0>>0?n:j}else j=2;if(!(c[f+(L<<2)+12>>2]|0)){E=c[f+(L<<2)+76>>2]|0;j=(E>>>0>=j>>>0&1)+E|0}a[b+L+82>>0]=j;l=c[(xb(L)|0)>>2]|0;l=ub(b,l)|0;m=zb(b,l)|0;if((m|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;m=E?0:m}l=c[(yb(L)|0)>>2]|0;l=ub(b,l)|0;n=zb(b,l)|0;if((n|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;n=E?0:n}J=c[3344+(L<<2)>>2]|0;K=c[3408+(L<<2)>>2]|0;r=(1285>>>L&1|0)!=0;if(r){o=h+K|0;l=h+(K+1)|0;p=h+(K+2)|0;q=h+(K+3)|0}else{q=(K<<4)+J|0;o=e+(q+-1)|0;l=e+(q+15)|0;p=e+(q+31)|0;q=e+(q+47)|0}A=a[o>>0]|0;y=a[l>>0]|0;F=a[p>>0]|0;E=a[q>>0]|0;do if(!(51>>>L&1)){x=K+-1|0;w=(x<<4)+J|0;o=a[e+w>>0]|0;q=a[e+(w+1)>>0]|0;s=a[e+(w+2)>>0]|0;u=a[e+(w+3)>>0]|0;t=a[e+(w+4)>>0]|0;l=a[e+(w+5)>>0]|0;v=a[e+(w+6)>>0]|0;p=a[e+(w+7)>>0]|0;if(r){D=v;C=u;u=p;B=q;z=s;v=h+x|0;break}else{D=v;C=u;u=p;B=q;z=s;v=e+(w+-1)|0;break}}else{D=a[g+(J+7)>>0]|0;C=a[g+(J+4)>>0]|0;t=a[g+(J+5)>>0]|0;l=a[g+(J+6)>>0]|0;o=a[g+(J+1)>>0]|0;u=a[g+(J+8)>>0]|0;B=a[g+(J+2)>>0]|0;z=a[g+(J+3)>>0]|0;v=g+J|0}while(0);v=a[v>>0]|0;switch(j|0){case 4:{if(!(I&(n|0)!=0)){k=1;j=51;break a}j=o&255;o=v&255;q=A&255;s=j+2|0;D=(s+q+(o<<1)|0)>>>2;u=D&255;k=B&255;o=o+2|0;v=((j<<1)+k+o|0)>>>2&255;j=z&255;s=((k<<1)+j+s|0)>>>2&255;z=y&255;o=(z+(q<<1)+o|0)>>>2;t=o&255;A=F&255;B=(q+2+(z<<1)+A|0)>>>2;q=u;p=t;n=B&255;m=v;l=s;j=((C&255)+2+k+(j<<1)|0)>>>2&255;k=u;r=v;o=(z+2+(A<<1)+(E&255)|0)>>>2&255|B<<8&65280|D<<24|o<<16&16711680;break}case 6:{if(!(I&(n|0)!=0)){k=1;j=51;break a}l=v&255;s=A&255;u=s+1|0;r=(u+l|0)>>>1&255;C=y&255;v=((s<<1)+2+C+l|0)>>>2&255;u=(u+C|0)>>>1&255;D=F&255;s=s+2|0;y=(s+(C<<1)+D|0)>>>2;A=(C+1+D|0)>>>1;E=E&255;j=o&255;s=(s+j+(l<<1)|0)>>>2&255;k=B&255;q=r;p=u;n=A&255;m=s;l=(k+2+(j<<1)+l|0)>>>2&255;j=((z&255)+2+(k<<1)+j|0)>>>2&255;k=v;t=y&255;o=y<<24|A<<16&16711680|(D+1+E|0)>>>1&255|C+2+(D<<1)+E<<6&65280;break}case 2:{do if(!I){if(G){j=((A&255)+2+(y&255)+(F&255)+(E&255)|0)>>>2;break}if(H)j=((C&255)+2+(z&255)+(B&255)+(o&255)|0)>>>2;else j=128}else j=((A&255)+4+(y&255)+(F&255)+(E&255)+(C&255)+(z&255)+(B&255)+(o&255)|0)>>>3;while(0);o=Z(j&255,16843009)|0;n=o&255;t=o>>>8&255;u=o>>>16&255;v=o>>>24&255;q=n;p=n;m=t;l=u;j=v;k=t;r=u;s=v;break}case 0:{if(!k){k=1;j=51;break a}q=o;p=o;n=o;m=B;l=z;j=C;k=B;r=z;s=C;t=B;u=z;v=C;o=(z&255)<<16|(C&255)<<24|(B&255)<<8|o&255;break}case 1:{if(!G){k=1;j=51;break a}j=Z(A&255,16843009)|0;s=Z(y&255,16843009)|0;v=Z(F&255,16843009)|0;q=j&255;p=s&255;n=v&255;m=j>>>8&255;l=j>>>16&255;j=j>>>24&255;k=s>>>8&255;r=s>>>16&255;s=s>>>24&255;t=v>>>8&255;u=v>>>16&255;v=v>>>24&255;o=Z(E&255,16843009)|0;break}case 7:{if(!k){k=1;j=51;break a}A=(m|0)==0;n=o&255;p=B&255;z=z&255;m=(z+1+p|0)>>>1&255;o=C&255;u=o+1|0;v=(u+z|0)>>>1&255;B=(A?C:t)&255;u=(u+B|0)>>>1&255;j=z+2|0;y=o+2|0;z=(y+p+(z<<1)|0)>>>2;o=(j+(o<<1)+B|0)>>>2;E=(A?C:l)&255;y=(y+E+(B<<1)|0)>>>2;q=(p+1+n|0)>>>1&255;p=(j+n+(p<<1)|0)>>>2&255;n=m;l=v;j=u;k=z&255;r=o&255;s=y&255;t=v;v=(B+1+E|0)>>>1&255;o=y<<16&16711680|z&255|(B+2+((A?C:D)&255)+(E<<1)|0)>>>2<<24|o<<8&65280;break}case 3:{if(!k){k=1;j=51;break a}n=(m|0)==0;q=B&255;m=z&255;p=m+2|0;k=C&255;B=k+2|0;m=(B+q+(m<<1)|0)>>>2&255;v=(n?C:t)&255;k=(p+(k<<1)+v|0)>>>2&255;E=(n?C:l)&255;B=(B+E+(v<<1)|0)>>>2;t=B&255;A=(n?C:D)&255;D=(v+2+A+(E<<1)|0)>>>2;v=D&255;C=(n?C:u)&255;E=(E+2+C+(A<<1)|0)>>>2;q=(p+(o&255)+(q<<1)|0)>>>2&255;p=m;n=k;l=k;j=t;r=t;s=v;u=v;v=E&255;o=(A+2+(C*3|0)|0)>>>2<<24|B&255|D<<8&65280|E<<16&16711680;break}case 5:{if(!(I&(n|0)!=0)){k=1;j=51;break a}n=v&255;u=o&255;t=(u+1+n|0)>>>1&255;x=B&255;E=(x+2+(u<<1)+n|0)>>>2;B=A&255;A=u+2|0;o=(A+B+(n<<1)|0)>>>2;u=(x+1+u|0)>>>1&255;s=z&255;A=((x<<1)+s+A|0)>>>2;v=(s+1+x|0)>>>1&255;C=C&255;D=y&255;q=t;p=o&255;n=(D+2+(B<<1)+n|0)>>>2&255;m=u;l=v;j=(C+1+s|0)>>>1&255;k=E&255;r=A&255;s=(C+2+x+(s<<1)|0)>>>2&255;o=A<<24|(B+2+(F&255)+(D<<1)|0)>>>2&255|E<<16&16711680|o<<8&65280;break}default:{if(!G){k=1;j=51;break a}s=A&255;j=y&255;m=F&255;l=(j+1+m|0)>>>1&255;o=E&255;k=(j+2+(m<<1)+o|0)>>>2&255;r=(m+1+o|0)>>>1&255;t=(m+2+(o*3|0)|0)>>>2&255;q=(s+1+j|0)>>>1&255;p=l;n=r;m=(s+2+(j<<1)+m|0)>>>2&255;j=k;s=t;u=E;v=E;o=o<<8|o|o<<16|o<<24}}E=(K<<4)+J|0;c[e+E>>2]=(l&255)<<16|(j&255)<<24|(m&255)<<8|q&255;c[e+(E+16)>>2]=(r&255)<<16|(s&255)<<24|(k&255)<<8|p&255;c[e+(E+32)>>2]=(u&255)<<16|(v&255)<<24|(t&255)<<8|n&255;c[e+(E+48)>>2]=o;Rb(e,f+(L<<6)+328|0,L);L=L+1|0;if(L>>>0>=16){k=0;j=51;break}}if((j|0)==51){i=N;return k|0}return 0}function Qb(b,e,f,g,h,j,k){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;y=i;m=b+200|0;l=zb(b,c[m>>2]|0)|0;n=(k|0)!=0;if((l|0)!=0&n){o=(cb(c[c[m>>2]>>2]|0)|0)==2;l=o?0:l}m=b+204|0;k=zb(b,c[m>>2]|0)|0;if((k|0)!=0&n){o=(cb(c[c[m>>2]>>2]|0)|0)==2;o=o?0:k}else o=k;m=b+212|0;k=zb(b,c[m>>2]|0)|0;if((k|0)!=0&n){n=(cb(c[c[m>>2]>>2]|0)|0)==2;k=n?0:k}w=(l|0)!=0;x=(o|0)!=0;v=w&x;u=v&(k|0)!=0;t=(l|0)==0;s=(o|0)==0;p=g;q=16;r=0;while(1){if((j|0)==1){if(t){l=1;k=29;break}else{n=e;b=8;m=h}while(1){b=b+-1|0;a[n>>0]=a[m>>0]|0;a[n+1>>0]=a[m>>0]|0;a[n+2>>0]=a[m>>0]|0;a[n+3>>0]=a[m>>0]|0;a[n+4>>0]=a[m>>0]|0;a[n+5>>0]=a[m>>0]|0;a[n+6>>0]=a[m>>0]|0;a[n+7>>0]=a[m>>0]|0;if(!b)break;else{n=n+8|0;m=m+1|0}}}else if((j|0)==2){if(s){l=1;k=29;break}else{n=p;b=e;m=8}while(1){n=n+1|0;m=m+-1|0;a[b>>0]=a[n>>0]|0;a[b+8>>0]=a[n>>0]|0;a[b+16>>0]=a[n>>0]|0;a[b+24>>0]=a[n>>0]|0;a[b+32>>0]=a[n>>0]|0;a[b+40>>0]=a[n>>0]|0;a[b+48>>0]=a[n>>0]|0;a[b+56>>0]=a[n>>0]|0;if(!m)break;else b=b+1|0}}else if(!j){m=p+1|0;do if(!v){if(x){n=((d[m>>0]|0)+2+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)|0)>>>2;b=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2;break}if(w){b=((d[h>>0]|0)+2+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)|0)>>>2;n=b}else{n=128;b=128}}else{n=((d[m>>0]|0)+4+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)+(d[h>>0]|0)+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)|0)>>>3;b=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2}while(0);n=n&255;o=b&255;nd(e|0,n|0,4)|0;nd(e+4|0,o|0,4)|0;nd(e+8|0,n|0,4)|0;nd(e+12|0,o|0,4)|0;nd(e+16|0,n|0,4)|0;nd(e+20|0,o|0,4)|0;g=e+32|0;nd(e+24|0,n|0,4)|0;nd(e+28|0,o|0,4)|0;if(w){o=d[h+4>>0]|0;n=d[h+5>>0]|0;b=d[h+6>>0]|0;m=d[h+7>>0]|0;k=(o+2+n+b+m|0)>>>2;if(x){l=k;n=(o+4+n+b+m+(d[p+5>>0]|0)+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>3}else{l=k;n=k}}else if(x){l=((d[m>>0]|0)+2+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)|0)>>>2;n=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2}else{l=128;n=128}b=l&255;o=n&255;nd(g|0,b|0,4)|0;nd(e+36|0,o|0,4)|0;nd(e+40|0,b|0,4)|0;nd(e+44|0,o|0,4)|0;nd(e+48|0,b|0,4)|0;nd(e+52|0,o|0,4)|0;nd(e+56|0,b|0,4)|0;nd(e+60|0,o|0,4)|0}else{if(!u){l=1;k=29;break}n=d[p+8>>0]|0;b=d[h+7>>0]|0;l=d[p>>0]|0;k=(((d[p+5>>0]|0)-(d[p+3>>0]|0)+((d[p+6>>0]|0)-(d[p+2>>0]|0)<<1)+(((d[p+7>>0]|0)-(d[p+1>>0]|0)|0)*3|0)+(n-l<<2)|0)*17|0)+16>>5;l=(((d[h+4>>0]|0)-(d[h+2>>0]|0)+(b-l<<2)+((d[h+5>>0]|0)-(d[h+1>>0]|0)<<1)+(((d[h+6>>0]|0)-(d[h>>0]|0)|0)*3|0)|0)*17|0)+16>>5;o=Z(k,-3)|0;n=(b+n<<4)+16+(Z(l,-3)|0)|0;b=e;m=8;while(1){m=m+-1|0;g=n+o|0;a[b>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+1>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+2>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+3>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+4>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+5>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+6>>0]=a[(g>>5)+3984>>0]|0;a[b+7>>0]=a[(g+k>>5)+3984>>0]|0;if(!m)break;else{n=n+l|0;b=b+8|0}}}Rb(e,f,q);g=q|1;Rb(e,f+64|0,g);Rb(e,f+128|0,g+1|0);Rb(e,f+192|0,q|3);r=r+1|0;if(r>>>0>=2){l=0;k=29;break}else{p=p+9|0;q=q+4|0;e=e+64|0;h=h+8|0;f=f+256|0}}if((k|0)==29){i=y;return l|0}return 0}function Rb(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;h=i;g=c[e>>2]|0;if((g|0)==16777215){i=h;return}m=f>>>0<16;l=m?16:8;m=m?f:f&3;m=(Z(c[3408+(m<<2)>>2]|0,l)|0)+(c[3344+(m<<2)>>2]|0)|0;n=b+m|0;p=c[e+4>>2]|0;j=b+(m+1)|0;f=d[j>>0]|0;a[n>>0]=a[3472+(g+512+(d[n>>0]|0))>>0]|0;n=c[e+8>>2]|0;k=b+(m+2)|0;o=d[k>>0]|0;a[j>>0]=a[3472+(p+512+f)>>0]|0;g=b+(m+3)|0;j=a[3472+((c[e+12>>2]|0)+512+(d[g>>0]|0))>>0]|0;a[k>>0]=a[3472+(n+512+o)>>0]|0;a[g>>0]=j;g=m+l|0;m=b+g|0;j=c[e+20>>2]|0;k=b+(g+1)|0;o=d[k>>0]|0;a[m>>0]=a[3472+((c[e+16>>2]|0)+512+(d[m>>0]|0))>>0]|0;m=c[e+24>>2]|0;n=b+(g+2)|0;f=d[n>>0]|0;a[k>>0]=a[3472+(j+512+o)>>0]|0;k=b+(g+3)|0;o=a[3472+((c[e+28>>2]|0)+512+(d[k>>0]|0))>>0]|0;a[n>>0]=a[3472+(m+512+f)>>0]|0;a[k>>0]=o;g=g+l|0;k=b+g|0;o=c[e+36>>2]|0;n=b+(g+1)|0;f=d[n>>0]|0;a[k>>0]=a[3472+((c[e+32>>2]|0)+512+(d[k>>0]|0))>>0]|0;k=c[e+40>>2]|0;m=b+(g+2)|0;j=d[m>>0]|0;a[n>>0]=a[3472+(o+512+f)>>0]|0;n=b+(g+3)|0;f=a[3472+((c[e+44>>2]|0)+512+(d[n>>0]|0))>>0]|0;a[m>>0]=a[3472+(k+512+j)>>0]|0;a[n>>0]=f;g=g+l|0;l=b+g|0;n=c[e+52>>2]|0;f=b+(g+1)|0;m=d[f>>0]|0;a[l>>0]=a[3472+((c[e+48>>2]|0)+512+(d[l>>0]|0))>>0]|0;l=c[e+56>>2]|0;j=b+(g+2)|0;k=d[j>>0]|0;a[f>>0]=a[3472+(n+512+m)>>0]|0;g=b+(g+3)|0;f=a[3472+((c[e+60>>2]|0)+512+(d[g>>0]|0))>>0]|0;a[j>>0]=a[3472+(l+512+k)>>0]|0;a[g>>0]=f;i=h;return} +function yc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;q=i;l=b+-1|0;k=a[b+1>>0]|0;m=d[l>>0]|0;n=d[b>>0]|0;r=m-n|0;p=f+4|0;do if((((r|0)>-1?r:0-r|0)>>>0<(c[p>>2]|0)>>>0?(o=d[b+-2>>0]|0,r=o-m|0,j=c[f+8>>2]|0,((r|0)>-1?r:0-r|0)>>>0>>0):0)?(h=k&255,k=h-n|0,((k|0)>-1?k:0-k|0)>>>0>>0):0)if(e>>>0<4){k=d[(c[f>>2]|0)+(e+-1)>>0]|0;k=Oa(~k,k+1|0,4-h+(n-m<<2)+o>>3)|0;o=a[3472+((n|512)-k)>>0]|0;a[l>>0]=a[3472+((m|512)+k)>>0]|0;a[b>>0]=o;break}else{a[l>>0]=(m+2+h+(o<<1)|0)>>>2;a[b>>0]=(n+2+(h<<1)+o|0)>>>2;break}while(0);l=b+g|0;m=b+(g+-1)|0;o=d[m>>0]|0;n=d[l>>0]|0;k=o-n|0;if(((k|0)>-1?k:0-k|0)>>>0>=(c[p>>2]|0)>>>0){i=q;return}k=d[b+(g+-2)>>0]|0;p=k-o|0;j=c[f+8>>2]|0;if(((p|0)>-1?p:0-p|0)>>>0>=j>>>0){i=q;return}h=d[b+(g+1)>>0]|0;g=h-n|0;if(((g|0)>-1?g:0-g|0)>>>0>=j>>>0){i=q;return}if(e>>>0<4){b=d[(c[f>>2]|0)+(e+-1)>>0]|0;b=Oa(~b,b+1|0,4-h+(n-o<<2)+k>>3)|0;g=a[3472+((n|512)-b)>>0]|0;a[m>>0]=a[3472+((o|512)+b)>>0]|0;a[l>>0]=g;i=q;return}else{a[m>>0]=(o+2+h+(k<<1)|0)>>>2;a[l>>0]=(n+2+(h<<1)+k|0)>>>2;i=q;return}}function zc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=i;if(e>>>0<4){n=d[(c[f>>2]|0)+(e+-1)>>0]|0;h=n+1|0;q=0-g|0;e=f+4|0;p=q<<1;o=f+8|0;n=~n;j=8;while(1){m=b+q|0;f=a[b+g>>0]|0;l=d[m>>0]|0;k=d[b>>0]|0;r=l-k|0;if((((r|0)>-1?r:0-r|0)>>>0<(c[e>>2]|0)>>>0?(t=d[b+p>>0]|0,r=t-l|0,s=c[o>>2]|0,((r|0)>-1?r:0-r|0)>>>0>>0):0)?(u=f&255,f=u-k|0,((f|0)>-1?f:0-f|0)>>>0>>0):0){r=Oa(n,h,4-u+(k-l<<2)+t>>3)|0;f=a[3472+((k|512)-r)>>0]|0;a[m>>0]=a[3472+((l|512)+r)>>0]|0;a[b>>0]=f}j=j+-1|0;if(!j)break;else b=b+1|0}i=v;return}else{o=0-g|0;m=f+4|0;n=o<<1;f=f+8|0;l=8;while(1){h=b+o|0;e=a[b+g>>0]|0;j=d[h>>0]|0;k=d[b>>0]|0;s=j-k|0;if((((s|0)>-1?s:0-s|0)>>>0<(c[m>>2]|0)>>>0?(p=d[b+n>>0]|0,s=p-j|0,q=c[f>>2]|0,((s|0)>-1?s:0-s|0)>>>0>>0):0)?(r=e&255,e=r-k|0,((e|0)>-1?e:0-e|0)>>>0>>0):0){a[h>>0]=(j+2+r+(p<<1)|0)>>>2;a[b>>0]=(k+2+(r<<1)+p|0)>>>2}l=l+-1|0;if(!l)break;else b=b+1|0}i=v;return}}function Ac(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;t=i;r=d[(c[f>>2]|0)+(e+-1)>>0]|0;s=r+1|0;l=0-g|0;h=f+4|0;q=l<<1;e=f+8|0;r=~r;l=b+l|0;m=a[b+g>>0]|0;k=d[l>>0]|0;j=d[b>>0]|0;u=k-j|0;f=c[h>>2]|0;if((((u|0)>-1?u:0-u|0)>>>0>>0?(o=d[b+q>>0]|0,u=o-k|0,n=c[e>>2]|0,((u|0)>-1?u:0-u|0)>>>0>>0):0)?(p=m&255,m=p-j|0,((m|0)>-1?m:0-m|0)>>>0>>0):0){p=Oa(r,s,4-p+(j-k<<2)+o>>3)|0;f=a[3472+((j|512)-p)>>0]|0;a[l>>0]=a[3472+((k|512)+p)>>0]|0;a[b>>0]=f;f=c[h>>2]|0}m=b+1|0;j=b+(1-g)|0;k=d[j>>0]|0;l=d[m>>0]|0;p=k-l|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}h=d[b+(q|1)>>0]|0;p=h-k|0;f=c[e>>2]|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}e=d[b+(g+1)>>0]|0;p=e-l|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}o=Oa(r,s,4-e+(l-k<<2)+h>>3)|0;p=a[3472+((l|512)-o)>>0]|0;a[j>>0]=a[3472+((k|512)+o)>>0]|0;a[m>>0]=p;i=t;return}function Bc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;p=c[b+4>>2]|0;q=c[b+8>>2]|0;if(!((d|0)==0|(d|0)==5)?(c[a+3384>>2]|0)==0:0)f=0;else{g=a+1220|0;e=0;do{f=ic(g,e)|0;e=e+1|0}while(e>>>0<16&(f|0)==0)}l=a+1176|0;n=c[l>>2]|0;if(n){m=c[a+1212>>2]|0;e=0;j=0;g=0;do{if(c[m+(j*216|0)+196>>2]|0)break;j=j+1|0;e=e+1|0;o=(e|0)==(p|0);g=(o&1)+g|0;e=o?0:e}while(j>>>0>>0);if((j|0)!=(n|0)){o=a+1212|0;n=c[o>>2]|0;j=Z(g,p)|0;if(e){l=a+1204|0;h=e;do{h=h+-1|0;m=h+j|0;Cc(n+(m*216|0)|0,b,g,h,d,f);c[n+(m*216|0)+196>>2]=1;c[l>>2]=(c[l>>2]|0)+1}while((h|0)!=0)}e=e+1|0;if(e>>>0

>>0){m=a+1204|0;do{l=e+j|0;k=n+(l*216|0)+196|0;if(!(c[k>>2]|0)){Cc(n+(l*216|0)|0,b,g,e,d,f);c[k>>2]=1;c[m>>2]=(c[m>>2]|0)+1}e=e+1|0}while((e|0)!=(p|0))}if(g){if(p){n=g+-1|0;h=Z(n,p)|0;e=a+1204|0;l=0-p|0;k=0;do{m=n;j=(c[o>>2]|0)+((k+h|0)*216|0)|0;while(1){Cc(j,b,m,k,d,f);c[j+196>>2]=1;c[e>>2]=(c[e>>2]|0)+1;if(!m)break;else{m=m+-1|0;j=j+(l*216|0)|0}}k=k+1|0}while((k|0)!=(p|0))}}else g=0;g=g+1|0;if(g>>>0>=q>>>0){i=r;return 0}m=a+1204|0;if(!p){i=r;return 0}do{e=c[o>>2]|0;l=Z(g,p)|0;k=0;do{h=k+l|0;j=e+(h*216|0)+196|0;if(!(c[j>>2]|0)){Cc(e+(h*216|0)|0,b,g,k,d,f);c[j>>2]=1;c[m>>2]=(c[m>>2]|0)+1}k=k+1|0}while((k|0)!=(p|0));g=g+1|0}while((g|0)!=(q|0));i=r;return 0}}if((d|0)==2|(d|0)==7)if((c[a+3384>>2]|0)==0|(f|0)==0)g=13;else g=14;else if(!f)g=13;else g=14;if((g|0)==13)id(c[b>>2]|0,128,Z(p*384|0,q)|0);else if((g|0)==14)hd(c[b>>2]|0,f,Z(p*384|0,q)|0);g=c[l>>2]|0;c[a+1204>>2]=g;if(!g){i=r;return 0}e=c[a+1212>>2]|0;f=0;do{c[e+(f*216|0)+8>>2]=1;f=f+1|0}while(f>>>0>>0);i=r;return 0}function Cc(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0;sa=i;i=i+480|0;qa=sa+96|0;ra=sa+32|0;m=sa+24|0;n=sa;na=c[e+4>>2]|0;u=c[e+8>>2]|0;Na(e,(Z(na,f)|0)+g|0);p=c[e>>2]|0;k=f<<4;l=g<<4;o=(Z(f<<8,na)|0)+l|0;c[b+20>>2]=40;c[b+8>>2]=0;c[b>>2]=6;c[b+12>>2]=0;c[b+16>>2]=0;c[b+24>>2]=0;do if((h|0)==2|(h|0)==7)id(qa,0,384);else{c[m>>2]=0;c[n+4>>2]=na;c[n+8>>2]=u;c[n>>2]=j;if(!j){id(qa,0,384);break}dc(qa,m,n,l,k,0,0,16,16);sc(e,qa);i=sa;return}while(0);id(ra,0,64);if((f|0)!=0?(c[b+((0-na|0)*216|0)+196>>2]|0)!=0:0){v=o-(na<<4)|0;E=v|1;D=v|3;E=(d[p+E>>0]|0)+(d[p+v>>0]|0)+(d[p+(E+1)>>0]|0)+(d[p+D>>0]|0)|0;$=v|7;D=(d[p+(D+2)>>0]|0)+(d[p+(D+1)>>0]|0)+(d[p+(D+3)>>0]|0)+(d[p+$>>0]|0)|0;F=(d[p+($+2)>>0]|0)+(d[p+($+1)>>0]|0)+(d[p+($+3)>>0]|0)+(d[p+($+4)>>0]|0)|0;v=(d[p+($+6)>>0]|0)+(d[p+($+5)>>0]|0)+(d[p+($+7)>>0]|0)+(d[p+(v|15)>>0]|0)|0;$=D+E|0;c[ra>>2]=F+$+(c[ra>>2]|0)+v;s=ra+4|0;c[s>>2]=$-F-v+(c[s>>2]|0);s=1}else{E=0;D=0;F=0;v=0;s=0}if((u+-1|0)!=(f|0)?(c[b+(na*216|0)+196>>2]|0)!=0:0){z=o+(na<<8)|0;w=z|1;x=z|3;w=(d[p+w>>0]|0)+(d[p+z>>0]|0)+(d[p+(w+1)>>0]|0)+(d[p+x>>0]|0)|0;r=z|7;x=(d[p+(x+2)>>0]|0)+(d[p+(x+1)>>0]|0)+(d[p+(x+3)>>0]|0)+(d[p+r>>0]|0)|0;y=(d[p+(r+2)>>0]|0)+(d[p+(r+1)>>0]|0)+(d[p+(r+3)>>0]|0)+(d[p+(r+4)>>0]|0)|0;z=(d[p+(r+6)>>0]|0)+(d[p+(r+5)>>0]|0)+(d[p+(r+7)>>0]|0)+(d[p+(z|15)>>0]|0)|0;r=x+w|0;c[ra>>2]=y+r+(c[ra>>2]|0)+z;t=ra+4|0;c[t>>2]=r-y-z+(c[t>>2]|0);t=1;r=s+1|0}else{t=0;w=0;x=0;y=0;z=0;r=s}if((g|0)!=0?(c[b+-20>>2]|0)!=0:0){_=o+-1|0;$=na<<4;j=na<<5;ma=na*48|0;C=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;h=na<<6;_=_+h|0;B=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;_=_+h|0;A=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;h=_+h|0;ma=(d[p+(h+$)>>0]|0)+(d[p+h>>0]|0)+(d[p+(h+j)>>0]|0)+(d[p+(h+ma)>>0]|0)|0;h=B+C|0;c[ra>>2]=A+h+(c[ra>>2]|0)+ma;j=ra+16|0;c[j>>2]=h-A-ma+(c[j>>2]|0);j=r+1|0;h=1}else{j=r;C=0;B=0;A=0;ma=0;h=0}do if((na+-1|0)!=(g|0)?(c[b+412>>2]|0)!=0:0){$=o+16|0;n=na<<4;m=na<<5;o=na*48|0;b=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;q=na<<6;$=$+q|0;l=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;$=$+q|0;k=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;q=$+q|0;o=(d[p+(q+n)>>0]|0)+(d[p+q>>0]|0)+(d[p+(q+m)>>0]|0)+(d[p+(q+o)>>0]|0)|0;p=j+1|0;q=h+1|0;j=l+b|0;c[ra>>2]=k+j+(c[ra>>2]|0)+o;m=ra+16|0;j=j-k-o+(c[m>>2]|0)|0;c[m>>2]=j;m=(r|0)==0;n=(h|0)!=0;if(!(m&n)){if(!m){m=1;j=p;h=q;l=21;break}}else c[ra+4>>2]=A+ma+B+C-b-l-k-o>>5;m=1;o=(s|0)!=0;b=(t|0)!=0;h=q;l=27}else l=17;while(0);if((l|0)==17){n=(h|0)!=0;if(!r){m=0;p=j;l=23}else{m=0;l=21}}if((l|0)==21){p=ra+4|0;c[p>>2]=c[p>>2]>>r+3;p=j;l=23}do if((l|0)==23){j=(h|0)==0;o=(s|0)!=0;b=(t|0)!=0;if(j&o&b){c[ra+16>>2]=F+v+D+E-z-y-x-w>>5;pa=m;h=p;oa=n;o=1;b=1;break}if(j){pa=m;h=p;oa=n}else{j=c[ra+16>>2]|0;l=27}}while(0);if((l|0)==27){c[ra+16>>2]=j>>h+3;pa=m;h=p;oa=n}if((h|0)==1)c[ra>>2]=c[ra>>2]>>4;else if((h|0)==2)c[ra>>2]=c[ra>>2]>>5;else if((h|0)==3)c[ra>>2]=(c[ra>>2]|0)*21>>10;else c[ra>>2]=c[ra>>2]>>6;Dc(ra);n=0;j=qa;m=ra;while(1){h=c[m+((n>>>2&3)<<2)>>2]|0;if((h|0)<0)h=0;else h=(h|0)>255?-1:h&255;a[j>>0]=h;h=n+1|0;if((h|0)==256)break;else{n=h;j=j+1|0;m=(h&63|0)==0?m+16|0:m}}ta=Z(u,na)|0;V=na<<3;Y=0-V|0;G=Y|1;_=G+1|0;$=Y|3;aa=$+1|0;ba=$+2|0;ca=$+3|0;da=Y|7;W=ra+4|0;ka=na<<6;H=ka|1;ea=H+1|0;fa=ka|3;ga=fa+1|0;ha=fa+2|0;ia=fa+3|0;ja=ka|7;I=V+-1|0;U=na<<4;J=U+-1|0;K=J+V|0;L=J+U|0;M=L+V|0;N=L+U|0;O=N+V|0;X=ra+16|0;P=V+8|0;Q=U|8;R=Q+V|0;S=Q+U|0;T=S+V|0;U=S+U|0;V=U+V|0;la=ta<<6;q=E;p=D;h=F;t=v;n=w;j=x;l=y;u=z;F=0;m=C;k=B;r=A;s=ma;E=(c[e>>2]|0)+((Z(f<<6,na)|0)+(g<<3)+(ta<<8))|0;while(1){id(ra,0,64);if(o){q=(d[E+G>>0]|0)+(d[E+Y>>0]|0)|0;p=(d[E+$>>0]|0)+(d[E+_>>0]|0)|0;z=(d[E+ba>>0]|0)+(d[E+aa>>0]|0)|0;A=(d[E+da>>0]|0)+(d[E+ca>>0]|0)|0;t=p+q|0;c[ra>>2]=z+t+(c[ra>>2]|0)+A;c[W>>2]=t-z-A+(c[W>>2]|0);t=1}else{z=h;A=t;t=0}if(b){B=(d[E+H>>0]|0)+(d[E+ka>>0]|0)|0;C=(d[E+fa>>0]|0)+(d[E+ea>>0]|0)|0;D=(d[E+ha>>0]|0)+(d[E+ga>>0]|0)|0;u=(d[E+ja>>0]|0)+(d[E+ia>>0]|0)|0;h=C+B|0;c[ra>>2]=D+h+(c[ra>>2]|0)+u;c[W>>2]=h-D-u+(c[W>>2]|0);h=t+1|0}else{B=n;C=j;D=l;h=t}if(oa){v=(d[E+I>>0]|0)+(d[E+-1>>0]|0)|0;w=(d[E+K>>0]|0)+(d[E+J>>0]|0)|0;x=(d[E+M>>0]|0)+(d[E+L>>0]|0)|0;y=(d[E+O>>0]|0)+(d[E+N>>0]|0)|0;t=w+v|0;c[ra>>2]=x+t+(c[ra>>2]|0)+y;c[X>>2]=t-x-y+(c[X>>2]|0);t=h+1|0;s=1}else{t=h;v=m;w=k;x=r;y=s;s=0}do if(pa){l=(d[E+P>>0]|0)+(d[E+8>>0]|0)|0;m=(d[E+R>>0]|0)+(d[E+Q>>0]|0)|0;j=(d[E+T>>0]|0)+(d[E+S>>0]|0)|0;n=(d[E+V>>0]|0)+(d[E+U>>0]|0)|0;t=t+1|0;s=s+1|0;k=m+l|0;c[ra>>2]=j+k+(c[ra>>2]|0)+n;k=k-j-n+(c[X>>2]|0)|0;c[X>>2]=k;r=(h|0)==0;if(!(r&oa))if(r){l=54;break}else{l=49;break}else{c[W>>2]=x+y+w+v-l-m-j-n>>4;l=54;break}}else if(!h){r=s;l=50}else l=49;while(0);if((l|0)==49){c[W>>2]=c[W>>2]>>h+2;r=s;l=50}do if((l|0)==50){l=0;s=(r|0)==0;if(s&o&b){c[X>>2]=z+A+p+q-u-D-C-B>>4;break}if(!s){k=c[X>>2]|0;s=r;l=54}}while(0);if((l|0)==54)c[X>>2]=k>>s+2;if((t|0)==1)c[ra>>2]=c[ra>>2]>>3;else if((t|0)==2)c[ra>>2]=c[ra>>2]>>4;else if((t|0)==3)c[ra>>2]=(c[ra>>2]|0)*21>>9;else c[ra>>2]=c[ra>>2]>>5;Dc(ra);s=0;r=qa+((F<<6)+256)|0;k=ra;while(1){t=c[k+((s>>>1&3)<<2)>>2]|0;if((t|0)<0)t=0;else t=(t|0)>255?-1:t&255;a[r>>0]=t;t=s+1|0;if((t|0)==64)break;else{s=t;r=r+1|0;k=(t&15|0)==0?k+16|0:k}}F=F+1|0;if((F|0)==2)break;else{h=z;t=A;n=B;j=C;l=D;m=v;k=w;r=x;s=y;E=E+la|0}}sc(e,qa);i=sa;return}function Dc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;h=i;f=a+4|0;b=c[f>>2]|0;g=a+16|0;d=c[g>>2]|0;e=c[a>>2]|0;if(!(b|d)){c[a+60>>2]=e;c[a+56>>2]=e;c[a+52>>2]=e;c[a+48>>2]=e;c[a+44>>2]=e;c[a+40>>2]=e;c[a+36>>2]=e;c[a+32>>2]=e;c[a+28>>2]=e;c[a+24>>2]=e;c[a+20>>2]=e;c[g>>2]=e;c[a+12>>2]=e;c[a+8>>2]=e;c[f>>2]=e;i=h;return}else{k=b+e|0;g=b>>1;j=g+e|0;g=e-g|0;b=e-b|0;c[a>>2]=d+k;e=d>>1;c[a+16>>2]=e+k;c[a+32>>2]=k-e;c[a+48>>2]=k-d;c[f>>2]=d+j;c[a+20>>2]=e+j;c[a+36>>2]=j-e;c[a+52>>2]=j-d;c[a+8>>2]=d+g;c[a+24>>2]=e+g;c[a+40>>2]=g-e;c[a+56>>2]=g-d;c[a+12>>2]=d+b;c[a+28>>2]=e+b;c[a+44>>2]=b-e;c[a+60>>2]=b-d;i=h;return}}function Ec(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;id(b,0,952);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b>>2]=d&1;do if(d){d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+4>>2]=d;if((d|0)==255){d=jb(a,16)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+8>>2]=d;d=jb(a,16)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+12>>2]=d;break}}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+16>>2]=d&1;do if(d){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+20>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+24>>2]=d&1;do if(d){d=jb(a,3)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+28>>2]=d;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+32>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+36>>2]=d&1;if(!d){c[b+40>>2]=2;c[b+44>>2]=2;c[b+48>>2]=2;break}d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+40>>2]=d;d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+44>>2]=d;d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+48>>2]=d;break}}else{c[b+28>>2]=5;c[b+40>>2]=2;c[b+44>>2]=2;c[b+48>>2]=2}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+52>>2]=d&1;if(d){d=b+56|0;e=nb(a,d)|0;if(e){d=e;i=h;return d|0}if((c[d>>2]|0)>>>0>5){d=1;i=h;return d|0}d=b+60|0;e=nb(a,d)|0;if(e){d=e;i=h;return d|0}if((c[d>>2]|0)>>>0>5){d=1;i=h;return d|0}}d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+64>>2]=d&1;do if(d){d=kb(a)|0;if((lb(a,32)|0)==-1|(d|0)==0){d=1;i=h;return d|0}c[b+68>>2]=d;d=kb(a)|0;if((lb(a,32)|0)==-1|(d|0)==0){d=1;i=h;return d|0}c[b+72>>2]=d;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+76>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;f=b+80|0;c[f>>2]=d&1;if(d){e=Fc(a,b+84|0)|0;if(e){d=e;i=h;return d|0}}else{c[b+84>>2]=1;c[b+96>>2]=288000001;c[b+224>>2]=288000001;c[b+480>>2]=24;c[b+484>>2]=24;c[b+488>>2]=24;c[b+492>>2]=24}e=jb(a,1)|0;if((e|0)==-1){d=1;i=h;return d|0}e=(e|0)==1;d=b+496|0;c[d>>2]=e&1;if(e){e=Fc(a,b+500|0)|0;if(e){d=e;i=h;return d|0}}else{c[b+500>>2]=1;c[b+512>>2]=240000001;c[b+640>>2]=240000001;c[b+896>>2]=24;c[b+900>>2]=24;c[b+904>>2]=24;c[b+908>>2]=24}if(!((c[f>>2]|0)==0?(c[d>>2]|0)==0:0))g=46;do if((g|0)==46){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+912>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+916>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+920>>2]=d&1;do if(d){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+924>>2]=(d|0)==1&1;e=b+928|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+932|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+936|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+940|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}d=nb(a,b+944|0)|0;if(d){i=h;return d|0}d=nb(a,b+948|0)|0;if(!d)break;i=h;return d|0}else{c[b+924>>2]=1;c[b+928>>2]=2;c[b+932>>2]=1;c[b+936>>2]=16;c[b+940>>2]=16;c[b+944>>2]=16;c[b+948>>2]=16}while(0);d=0;i=h;return d|0}function Fc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;d=nb(a,b)|0;if(d){i=k;return d|0}d=(c[b>>2]|0)+1|0;c[b>>2]=d;if(d>>>0>32){d=1;i=k;return d|0}d=jb(a,4)|0;if((d|0)==-1){d=1;i=k;return d|0}j=b+4|0;c[j>>2]=d;e=jb(a,4)|0;if((e|0)==-1){d=1;i=k;return d|0}h=b+8|0;c[h>>2]=e;a:do if(c[b>>2]|0){g=0;while(1){f=b+(g<<2)+12|0;d=nb(a,f)|0;if(d){e=17;break}e=c[f>>2]|0;if((e|0)==-1){d=1;e=17;break}d=e+1|0;c[f>>2]=d;c[f>>2]=d<<(c[j>>2]|0)+6;f=b+(g<<2)+140|0;d=nb(a,f)|0;if(d){e=17;break}e=c[f>>2]|0;if((e|0)==-1){d=1;e=17;break}e=e+1|0;c[f>>2]=e;c[f>>2]=e<<(c[h>>2]|0)+4;e=jb(a,1)|0;if((e|0)==-1){d=1;e=17;break}c[b+(g<<2)+268>>2]=(e|0)==1&1;g=g+1|0;if(g>>>0>=(c[b>>2]|0)>>>0)break a}if((e|0)==17){i=k;return d|0}}while(0);d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+396>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+400>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+404>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+408>>2]=d;d=0;i=k;return d|0}function Gc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;a:do if(!(c[d+284>>2]|0))o=0;else{h=0;while(1){j=c[d+(h*20|0)+288>>2]|0;if((j|0)==5){o=1;break a}else if(!j)break;h=h+1|0}o=0}while(0);j=c[b+16>>2]|0;if((j|0)==1){if((c[e>>2]|0)!=5){f=c[a+12>>2]|0;if((c[a+8>>2]|0)>>>0>(c[d+12>>2]|0)>>>0)f=(c[b+12>>2]|0)+f|0}else f=0;m=c[b+36>>2]|0;h=(m|0)==0;if(h)j=0;else j=(c[d+12>>2]|0)+f|0;e=(c[e+4>>2]|0)==0;k=((e&(j|0)!=0)<<31>>31)+j|0;l=(k|0)!=0;if(l){g=k+-1|0;n=(g>>>0)%(m>>>0)|0;g=(g>>>0)/(m>>>0)|0}else{n=0;g=0}if(h)j=0;else{k=c[b+40>>2]|0;j=0;h=0;do{j=(c[k+(h<<2)>>2]|0)+j|0;h=h+1|0}while(h>>>0>>0)}if(l){g=Z(j,g)|0;k=c[b+40>>2]|0;j=0;do{g=(c[k+(j<<2)>>2]|0)+g|0;j=j+1|0}while(j>>>0<=n>>>0)}else g=0;if(e)j=(c[b+28>>2]|0)+g|0;else j=g;g=(c[d+32>>2]|0)+(c[b+32>>2]|0)|0;h=a+12|0;if(!o){b=((g|0)<0?g:0)+j+(c[d+28>>2]|0)|0;c[h>>2]=f;c[a+8>>2]=c[d+12>>2];i=p;return b|0}else{c[h>>2]=0;c[a+8>>2]=0;b=0;i=p;return b|0}}else if(!j){if((c[e>>2]|0)!=5){h=c[a>>2]|0;j=c[d+20>>2]|0;if(h>>>0>j>>>0?(k=c[b+20>>2]|0,(h-j|0)>>>0>=k>>>1>>>0):0){h=(c[a+4>>2]|0)+k|0;k=a}else{k=a;m=11}}else{c[a+4>>2]=0;c[a>>2]=0;j=c[d+20>>2]|0;h=0;k=a;m=11}do if((m|0)==11){if(j>>>0>h>>>0?(g=c[b+20>>2]|0,(j-h|0)>>>0>g>>>1>>>0):0){h=(c[a+4>>2]|0)-g|0;break}h=c[a+4>>2]|0}while(0);if(!(c[e+4>>2]|0)){b=c[d+24>>2]|0;b=j+h+((b|0)<0?b:0)|0;i=p;return b|0}c[a+4>>2]=h;f=c[d+24>>2]|0;g=(f|0)<0;if(!o){c[k>>2]=j;b=j+h+(g?f:0)|0;i=p;return b|0}else{c[a+4>>2]=0;c[k>>2]=g?0-f|0:0;b=0;i=p;return b|0}}else{if((c[e>>2]|0)==5){k=0;g=0;f=a+12|0}else{j=c[d+12>>2]|0;f=a+12|0;h=c[f>>2]|0;if((c[a+8>>2]|0)>>>0>j>>>0)h=(c[b+12>>2]|0)+h|0;k=h;g=(j+h<<1)+(((c[e+4>>2]|0)==0)<<31>>31)|0}if(!o){c[f>>2]=k;c[a+8>>2]=c[d+12>>2];b=g;i=p;return b|0}else{c[f>>2]=0;c[a+8>>2]=0;b=0;i=p;return b|0}}return 0}function Hc(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;Ab(a);e=fd(2112)|0;c[a+3376>>2]=e;if(e)if(!b)b=0;else{c[a+1216>>2]=1;b=0}else b=1;i=d;return b|0}function Ic(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;i=i+208|0;l=r+204|0;p=r;g=r+112|0;h=r+40|0;q=r+16|0;j=r+12|0;n=r+8|0;c[j>>2]=0;o=a+3344|0;if((c[o>>2]|0)!=0?(c[a+3348>>2]|0)==(b|0):0){b=a+3356|0;c[q+0>>2]=c[b+0>>2];c[q+4>>2]=c[b+4>>2];c[q+8>>2]=c[b+8>>2];c[q+12>>2]=c[b+12>>2];c[q+4>>2]=c[q>>2];c[q+8>>2]=0;c[q+16>>2]=0;c[f>>2]=c[a+3352>>2]}else k=4;do if((k|0)==4)if(!(Pa(b,d,q,f)|0)){d=a+3356|0;c[d+0>>2]=c[q+0>>2];c[d+4>>2]=c[q+4>>2];c[d+8>>2]=c[q+8>>2];c[d+12>>2]=c[q+12>>2];c[d+16>>2]=c[q+16>>2];c[a+3352>>2]=c[f>>2];c[a+3348>>2]=b;break}else{n=3;i=r;return n|0}while(0);c[o>>2]=0;if(sb(q,p)|0){n=3;i=r;return n|0}if(((c[p>>2]|0)+-1|0)>>>0>11){n=0;i=r;return n|0}b=Ib(q,p,a,j)|0;if(!b){do if(!(c[j>>2]|0))k=19;else{if((c[a+1184>>2]|0)!=0?(c[a+16>>2]|0)!=0:0){if(c[a+3380>>2]|0){n=3;i=r;return n|0}if(!(c[a+1188>>2]|0)){m=a+1220|0;n=a+1336|0;c[n>>2]=jc(m)|0;nc(m);Bc(a,n,0)|0}else Bc(a,a+1336|0,c[a+1372>>2]|0)|0;c[f>>2]=0;c[o>>2]=1;c[a+1180>>2]=0;g=a+1336|0;b=a+1360|0;break}c[a+1188>>2]=0;c[a+1180>>2]=0;k=19}while(0);do if((k|0)==19){b=c[p>>2]|0;if((b|0)==7)if(!(Qa(q,g)|0)){Bb(a,g)|0;n=0;i=r;return n|0}else{n=g+40|0;gd(c[n>>2]|0);c[n>>2]=0;n=g+84|0;gd(c[n>>2]|0);c[n>>2]=0;n=3;i=r;return n|0}else if((b|0)==1|(b|0)==5){k=a+1180|0;if(c[a+1180>>2]|0){n=0;i=r;return n|0}c[a+1184>>2]=1;if(Fb(a)|0){c[a+1204>>2]=0;c[a+1208>>2]=e;Ua(q,l)|0;j=a+8|0;d=c[j>>2]|0;b=Db(a,c[l>>2]|0,(c[p>>2]|0)==5&1)|0;if(b){c[a+4>>2]=256;c[a+12>>2]=0;c[j>>2]=32;c[a+16>>2]=0;c[a+3380>>2]=0;n=(b|0)==65535?5:4;i=r;return n|0}if((d|0)!=(c[j>>2]|0)){d=c[a+16>>2]|0;c[n>>2]=1;b=c[a>>2]|0;if(b>>>0<32)b=c[a+(b<<2)+20>>2]|0;else b=0;c[f>>2]=0;c[o>>2]=1;if((((((c[p>>2]|0)==5?(l=_a(n,q,d,c[a+12>>2]|0,5)|0,(c[n>>2]|l|0)==0):0)?(m=a+1220|0,!((c[a+1276>>2]|0)!=0|(b|0)==0)):0)?(c[b+52>>2]|0)==(c[d+52>>2]|0):0)?(c[b+56>>2]|0)==(c[d+56>>2]|0):0)?(c[b+88>>2]|0)==(c[d+88>>2]|0):0)qc(m);else c[a+1280>>2]=0;c[a>>2]=c[j>>2];n=2;i=r;return n|0}}if(c[a+3380>>2]|0){n=3;i=r;return n|0}h=a+1368|0;j=a+2356|0;b=a+16|0;if(Ta(q,j,c[b>>2]|0,c[a+12>>2]|0,p)|0){n=3;i=r;return n|0}if(!(Fb(a)|0))d=a+1220|0;else{d=a+1220|0;if((c[p>>2]|0)!=5?(oc(d,c[a+2368>>2]|0,(c[p+4>>2]|0)!=0&1,c[(c[b>>2]|0)+48>>2]|0)|0)!=0:0){n=3;i=r;return n|0}c[a+1336>>2]=jc(d)|0}od(h|0,j|0,988)|0;c[a+1188>>2]=1;b=a+1360|0;l=p;m=c[l+4>>2]|0;n=b;c[n>>2]=c[l>>2];c[n+4>>2]=m;Hb(a,c[a+1432>>2]|0);nc(d);if(gc(d,a+1436|0,c[a+1380>>2]|0,c[a+1412>>2]|0)|0){n=3;i=r;return n|0}g=a+1336|0;if($a(q,a,g,h)|0){ab(a,c[h>>2]|0);n=3;i=r;return n|0}if(!(Gb(a)|0)){n=0;i=r;return n|0}else{c[k>>2]=1;break}}else if((b|0)==8)if(!(Sa(q,h)|0)){Cb(a,h)|0;n=0;i=r;return n|0}else{n=h+20|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+24|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+28|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+44|0;gd(c[n>>2]|0);c[n>>2]=0;n=3;i=r;return n|0}else{n=0;i=r;return n|0}}while(0);uc(g,c[a+1212>>2]|0);Eb(a);j=Gc(a+1284|0,c[a+16>>2]|0,a+1368|0,b)|0;d=a+1188|0;do if(c[d>>2]|0){h=a+1220|0;if(!(c[a+1364>>2]|0)){hc(h,0,g,c[a+1380>>2]|0,j,(c[b>>2]|0)==5&1,c[a+1208>>2]|0,c[a+1204>>2]|0)|0;break}else{hc(h,a+1644|0,g,c[a+1380>>2]|0,j,(c[b>>2]|0)==5&1,c[a+1208>>2]|0,c[a+1204>>2]|0)|0;break}}while(0);c[a+1184>>2]=0;c[d>>2]=0;n=1;i=r;return n|0}else if((b|0)==65520){n=4;i=r;return n|0}else{n=3;i=r;return n|0}return 0}function Jc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;e=0;do{d=a+(e<<2)+20|0;b=c[d>>2]|0;if(b){gd(c[b+40>>2]|0);c[(c[d>>2]|0)+40>>2]=0;gd(c[(c[d>>2]|0)+84>>2]|0);c[(c[d>>2]|0)+84>>2]=0;gd(c[d>>2]|0);c[d>>2]=0}e=e+1|0}while((e|0)!=32);e=0;do{d=a+(e<<2)+148|0;b=c[d>>2]|0;if(b){gd(c[b+20>>2]|0);c[(c[d>>2]|0)+20>>2]=0;gd(c[(c[d>>2]|0)+24>>2]|0);c[(c[d>>2]|0)+24>>2]=0;gd(c[(c[d>>2]|0)+28>>2]|0);c[(c[d>>2]|0)+28>>2]=0;gd(c[(c[d>>2]|0)+44>>2]|0);c[(c[d>>2]|0)+44>>2]=0;gd(c[d>>2]|0);c[d>>2]=0}e=e+1|0}while((e|0)!=256);b=a+3376|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+1212|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+1172|0;gd(c[b>>2]|0);c[b>>2]=0;mc(a+1220|0);i=f;return}function Kc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=i;a=pc(a+1220|0)|0;if(!a){a=0;i=f;return a|0}c[b>>2]=c[a+4>>2];c[d>>2]=c[a+12>>2];c[e>>2]=c[a+8>>2];a=c[a>>2]|0;i=f;return a|0}function Lc(a){a=a|0;var b=0;b=i;a=c[a+16>>2]|0;if(!a){a=0;i=b;return a|0}a=c[a+52>>2]|0;i=b;return a|0}function Mc(a){a=a|0;var b=0;b=i;a=c[a+16>>2]|0;if(!a){a=0;i=b;return a|0}a=c[a+56>>2]|0;i=b;return a|0}function Nc(a){a=a|0;var b=0;b=i;qc(a+1220|0);i=b;return}function Oc(a){a=a|0;var b=0;b=i;a=(Jb(a)|0)==0&1;i=b;return a|0}function Pc(a){a=a|0;var b=0,d=0;d=i;a=c[a+16>>2]|0;if(((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(b=c[a+84>>2]|0,(b|0)!=0):0)?(c[b+24>>2]|0)!=0:0)?(c[b+32>>2]|0)!=0:0){a=1;i=d;return a|0}a=0;i=d;return a|0}function Qc(a){a=a|0;var b=0,d=0;d=i;a=c[a+16>>2]|0;if(((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(b=c[a+84>>2]|0,(b|0)!=0):0)?(c[b+24>>2]|0)!=0:0)?(c[b+36>>2]|0)!=0:0)a=c[b+48>>2]|0;else a=2;i=d;return a|0}function Rc(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0;h=i;a=c[a+16>>2]|0;if((a|0)!=0?(c[a+60>>2]|0)!=0:0){c[b>>2]=1;b=a+64|0;c[d>>2]=c[b>>2]<<1;c[e>>2]=(c[a+52>>2]<<4)-((c[a+68>>2]|0)+(c[b>>2]|0)<<1);b=a+72|0;c[f>>2]=c[b>>2]<<1;a=(c[a+56>>2]<<4)-((c[a+76>>2]|0)+(c[b>>2]|0)<<1)|0;c[g>>2]=a;i=h;return}c[b>>2]=0;c[d>>2]=0;c[e>>2]=0;c[f>>2]=0;a=0;c[g>>2]=a;i=h;return}function Sc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;f=i;a=c[a+16>>2]|0;a:do if((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(e=c[a+84>>2]|0,(e|0)!=0):0)?(c[e>>2]|0)!=0:0){a=c[e+4>>2]|0;do switch(a|0){case 8:{e=11;a=32;break a}case 13:{e=99;a=160;break a}case 12:{e=33;a=64;break a}case 6:{e=11;a=24;break a}case 7:{e=11;a=20;break a}case 255:{a=c[e+8>>2]|0;e=c[e+12>>2]|0;g=(a|0)==0|(e|0)==0;e=g?0:e;a=g?0:a;break a}case 5:{e=33;a=40;break a}case 4:{e=11;a=16;break a}case 3:{e=11;a=10;break a}case 1:case 0:{e=a;break a}case 2:{e=11;a=12;break a}case 10:{e=11;a=18;break a}case 9:{e=33;a=80;break a}case 11:{e=11;a=15;break a}default:{e=0;a=0;break a}}while(0)}else{e=1;a=1}while(0);c[b>>2]=a;c[d>>2]=e;i=f;return}function Tc(a){a=a|0;a=c[a+16>>2]|0;if(!a)a=0;else a=c[a>>2]|0;return a|0}function Uc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;do if(a){d=fd(3396)|0;if(d){e=d+8|0;if(!(Hc(e,b)|0)){c[d>>2]=1;c[d+4>>2]=0;c[a>>2]=d;d=0;break}else{Jc(e);gd(d);d=-4;break}}else d=-4}else d=-1;while(0);i=f;return d|0}function Vc(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;if((a|0)==0|(b|0)==0){a=-1;i=e;return a|0}d=a+8|0;if(!(c[a+24>>2]|0)){a=-6;i=e;return a|0}if(!(c[a+20>>2]|0)){a=-6;i=e;return a|0}c[b+4>>2]=(Lc(d)|0)<<4;c[b+8>>2]=(Mc(d)|0)<<4;c[b+12>>2]=Pc(d)|0;c[b+16>>2]=Qc(d)|0;Rc(d,b+28|0,b+32|0,b+36|0,b+40|0,b+44|0);Sc(d,b+20|0,b+24|0);c[b>>2]=Tc(d)|0;a=0;i=e;return a|0}function Wc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;m=i;i=i+16|0;j=m;a:do if((!((b|0)==0|(d|0)==0)?(f=c[b>>2]|0,(f|0)!=0):0)?(g=c[b+4>>2]|0,(g|0)!=0):0)if((a|0)!=0?(e=c[a>>2]|0,(e|0)!=0):0){c[d>>2]=0;c[j>>2]=0;k=a+8|0;c[a+3392>>2]=c[b+12>>2];h=b+8|0;b=1;while(1){if((e|0)==2){l=8;break}e=Ic(k,f,g,c[h>>2]|0,j)|0;n=c[j>>2]|0;f=f+n|0;g=g-n|0;g=(g|0)<0?0:g;c[d>>2]=f;if((e|0)==5){b=-4;break a}else if((e|0)==4){e=(Oc(k)|0|g|0)==0;b=e?-2:b}else if((e|0)==2)break;else if((e|0)==1){l=13;break}if(!g)break a;e=c[a>>2]|0}if((l|0)==8){c[a>>2]=1;c[d>>2]=f+(c[j>>2]|0)}else if((l|0)==13){b=a+4|0;c[b>>2]=(c[b>>2]|0)+1;b=(g|0)==0?2:3;break}b=a+1288|0;if((c[b>>2]|0)!=0?(c[a+1244>>2]|0)!=(c[a+1248>>2]|0):0){c[b>>2]=0;c[a>>2]=2;b=3}else b=4}else b=-3;else b=-1;while(0);i=m;return b|0}function Xc(a){a=a|0;c[a>>2]=2;c[a+4>>2]=3;return}function Yc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;h=i;i=i+16|0;f=h+8|0;e=h+4|0;g=h;if((a|0)==0|(b|0)==0){a=-1;i=h;return a|0}a=a+8|0;if(d)Nc(a);a=Kc(a,g,e,f)|0;if(!a){a=0;i=h;return a|0}c[b>>2]=a;c[b+4>>2]=c[g>>2];c[b+8>>2]=c[e>>2];c[b+12>>2]=c[f>>2];a=2;i=h;return a|0}function Zc(a){a=a|0;var b=0,d=0;d=i;b=jd(a)|0;c[1792]=b;c[1791]=b;c[1790]=a;c[1793]=b+a;i=d;return b|0}function _c(a){a=a|0;c[1790]=a;return}function $c(){var a=0;a=i;c[1786]=c[1791];c[1787]=c[1790];do bd()|0;while((c[1787]|0)!=0);i=a;return}function ad(){var a=0,b=0;b=i;if(Uc(7176,0)|0){da(7280)|0;a=c[1784]|0;if(a)kd(a)}else{c[1796]=1;c[1798]=1}i=b;return -1}function bd(){var a=0,b=0,d=0;b=i;c[1788]=c[1798];a=Wc(c[1794]|0,7144,7200)|0;switch(a|0){case 1:case -2:{c[1787]=0;i=b;return a|0}case 4:{if(Vc(c[1794]|0,7208)|0){a=-1;i=b;return a|0}c[1814]=(Z((c[1803]|0)*3|0,c[1804]|0)|0)>>>1;ra();a=c[1800]|0;c[1787]=(c[1786]|0)-a+(c[1787]|0);c[1786]=a;a=0;i=b;return a|0}case 2:{c[1787]=0;break}case 3:{d=c[1800]|0;c[1787]=(c[1786]|0)-d+(c[1787]|0);c[1786]=d;break}default:{i=b;return a|0}}c[1798]=(c[1798]|0)+1;if((Yc(c[1794]|0,7264,0)|0)!=2){i=b;return a|0}do{c[1796]=(c[1796]|0)+1;ca(c[1816]|0,c[1803]|0,c[1804]|0)}while((Yc(c[1794]|0,7264,0)|0)==2);i=b;return a|0}function cd(){var a=0,b=0;b=i;a=c[1784]|0;if(a)kd(a);i=b;return}function dd(){var a=0,b=0;b=i;i=i+16|0;a=b;Xc(a);i=b;return c[a>>2]|0}function ed(){var a=0,b=0;b=i;i=i+16|0;a=b;Xc(a);i=b;return c[a+4>>2]|0}function fd(a){a=a|0;var b=0;b=i;a=jd(a)|0;i=b;return a|0}function gd(a){a=a|0;var b=0;b=i;kd(a);i=b;return}function hd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=i;od(a|0,b|0,c|0)|0;i=d;return}function id(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=i;nd(a|0,b&255|0,c|0)|0;i=d;return}function jd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0;L=i;do if(a>>>0<245){if(a>>>0<11)p=16;else p=a+11&-8;a=p>>>3;l=c[1828]|0;k=l>>>a;if(k&3){g=(k&1^1)+a|0;b=g<<1;h=7352+(b<<2)|0;b=7352+(b+2<<2)|0;e=c[b>>2]|0;j=e+8|0;f=c[j>>2]|0;do if((h|0)!=(f|0)){if(f>>>0<(c[1832]|0)>>>0)ka();d=f+12|0;if((c[d>>2]|0)==(e|0)){c[d>>2]=h;c[b>>2]=f;break}else ka()}else c[1828]=l&~(1<>2]=x|3;x=e+(x|4)|0;c[x>>2]=c[x>>2]|1;x=j;i=L;return x|0}j=c[1830]|0;if(p>>>0>j>>>0){if(k){g=2<>>12&16;g=g>>>a;h=g>>>5&8;g=g>>>h;d=g>>>2&4;g=g>>>d;e=g>>>1&2;g=g>>>e;f=g>>>1&1;f=(h|a|d|e|f)+(g>>>f)|0;g=f<<1;e=7352+(g<<2)|0;g=7352+(g+2<<2)|0;d=c[g>>2]|0;a=d+8|0;h=c[a>>2]|0;do if((e|0)!=(h|0)){if(h>>>0<(c[1832]|0)>>>0)ka();j=h+12|0;if((c[j>>2]|0)==(d|0)){c[j>>2]=e;c[g>>2]=h;m=c[1830]|0;break}else ka()}else{c[1828]=l&~(1<>2]=p|3;b=d+p|0;c[d+(p|4)>>2]=k|1;c[d+x>>2]=k;if(m){e=c[1833]|0;g=m>>>3;h=g<<1;f=7352+(h<<2)|0;j=c[1828]|0;g=1<>2]|0;if(h>>>0<(c[1832]|0)>>>0)ka();else{n=j;o=h}}else{c[1828]=j|g;n=7352+(h+2<<2)|0;o=f}c[n>>2]=e;c[o+12>>2]=e;c[e+8>>2]=o;c[e+12>>2]=f}c[1830]=k;c[1833]=b;x=a;i=L;return x|0}k=c[1829]|0;if(k){l=(k&0-k)+-1|0;w=l>>>12&16;l=l>>>w;v=l>>>5&8;l=l>>>v;x=l>>>2&4;l=l>>>x;j=l>>>1&2;l=l>>>j;m=l>>>1&1;m=c[7616+((v|w|x|j|m)+(l>>>m)<<2)>>2]|0;l=(c[m+4>>2]&-8)-p|0;j=m;while(1){d=c[j+16>>2]|0;if(!d){d=c[j+20>>2]|0;if(!d)break}j=(c[d+4>>2]&-8)-p|0;x=j>>>0>>0;l=x?j:l;j=d;m=x?d:m}k=c[1832]|0;if(m>>>0>>0)ka();b=m+p|0;if(m>>>0>=b>>>0)ka();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){e=0;break}}while(1){f=j+20|0;g=c[f>>2]|0;if(g){j=g;h=f;continue}f=j+16|0;g=c[f>>2]|0;if(!g)break;else{j=g;h=f}}if(h>>>0>>0)ka();else{c[h>>2]=0;e=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ka();j=f+12|0;if((c[j>>2]|0)!=(m|0))ka();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;e=g;break}else ka()}while(0);do if(a){j=c[m+28>>2]|0;h=7616+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=e;if(!e){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=e;else c[a+20>>2]=e;if(!e)break}h=c[1832]|0;if(e>>>0>>0)ka();c[e+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ka();else{c[e+16>>2]=j;c[j+24>>2]=e;break}while(0);f=c[m+20>>2]|0;if(f)if(f>>>0<(c[1832]|0)>>>0)ka();else{c[e+20>>2]=f;c[f+24>>2]=e;break}}while(0);if(l>>>0<16){x=l+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}else{c[m+4>>2]=p|3;c[m+(p|4)>>2]=l|1;c[m+(l+p)>>2]=l;d=c[1830]|0;if(d){e=c[1833]|0;g=d>>>3;h=g<<1;f=7352+(h<<2)|0;j=c[1828]|0;g=1<>2]|0;if(h>>>0<(c[1832]|0)>>>0)ka();else{r=j;q=h}}else{c[1828]=j|g;r=7352+(h+2<<2)|0;q=f}c[r>>2]=e;c[q+12>>2]=e;c[e+8>>2]=q;c[e+12>>2]=f}c[1830]=l;c[1833]=b}x=m+8|0;i=L;return x|0}}}else if(a>>>0<=4294967231){a=a+11|0;p=a&-8;m=c[1829]|0;if(m){h=0-p|0;a=a>>>8;if(a)if(p>>>0>16777215)l=31;else{q=(a+1048320|0)>>>16&8;r=a<>>16&4;r=r<>>16&2;l=14-(o|q|l)+(r<>>15)|0;l=p>>>(l+7|0)&1|l<<1}else l=0;j=c[7616+(l<<2)>>2]|0;a:do if(!j){a=0;k=0}else{if((l|0)==31)k=0;else k=25-(l>>>1)|0;f=h;a=0;e=p<>2]&-8;h=g-p|0;if(h>>>0>>0)if((g|0)==(p|0)){a=j;k=j;break a}else k=j;else h=f;r=c[j+20>>2]|0;j=c[j+(e>>>31<<2)+16>>2]|0;a=(r|0)==0|(r|0)==(j|0)?a:r;if(!j)break;else{f=h;e=e<<1}}}while(0);if((a|0)==0&(k|0)==0){a=2<>>12&16;r=r>>>n;m=r>>>5&8;r=r>>>m;o=r>>>2&4;r=r>>>o;q=r>>>1&2;r=r>>>q;a=r>>>1&1;a=c[7616+((m|n|o|q|a)+(r>>>a)<<2)>>2]|0}if(!a){n=h;m=k}else while(1){r=(c[a+4>>2]&-8)-p|0;j=r>>>0>>0;h=j?r:h;k=j?a:k;j=c[a+16>>2]|0;if(j){a=j;continue}a=c[a+20>>2]|0;if(!a){n=h;m=k;break}}if((m|0)!=0?n>>>0<((c[1830]|0)-p|0)>>>0:0){k=c[1832]|0;if(m>>>0>>0)ka();o=m+p|0;if(m>>>0>=o>>>0)ka();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){b=0;break}}while(1){f=j+20|0;g=c[f>>2]|0;if(g){j=g;h=f;continue}f=j+16|0;g=c[f>>2]|0;if(!g)break;else{j=g;h=f}}if(h>>>0>>0)ka();else{c[h>>2]=0;b=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ka();j=f+12|0;if((c[j>>2]|0)!=(m|0))ka();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;b=g;break}else ka()}while(0);do if(a){j=c[m+28>>2]|0;h=7616+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=b;if(!b){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=b;else c[a+20>>2]=b;if(!b)break}h=c[1832]|0;if(b>>>0>>0)ka();c[b+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ka();else{c[b+16>>2]=j;c[j+24>>2]=b;break}while(0);j=c[m+20>>2]|0;if(j)if(j>>>0<(c[1832]|0)>>>0)ka();else{c[b+20>>2]=j;c[j+24>>2]=b;break}}while(0);b:do if(n>>>0>=16){c[m+4>>2]=p|3;c[m+(p|4)>>2]=n|1;c[m+(n+p)>>2]=n;j=n>>>3;if(n>>>0<256){g=j<<1;d=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(e>>>0>=(c[1832]|0)>>>0){t=f;u=e;break}ka()}while(0);c[t>>2]=o;c[u+12>>2]=o;c[m+(p+8)>>2]=u;c[m+(p+12)>>2]=d;break}d=n>>>8;if(d)if(n>>>0>16777215)f=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|w|f)+(x<>>15)|0;f=n>>>(f+7|0)&1|f<<1}else f=0;h=7616+(f<<2)|0;c[m+(p+28)>>2]=f;c[m+(p+20)>>2]=0;c[m+(p+16)>>2]=0;j=c[1829]|0;g=1<>2]=o;c[m+(p+24)>>2]=h;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break}j=c[h>>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;c:do if((c[j+4>>2]&-8|0)!=(n|0)){f=n<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(n|0)){v=h;break c}else{f=f<<1;j=h}}if(g>>>0<(c[1832]|0)>>>0)ka();else{c[g>>2]=o;c[m+(p+24)>>2]=j;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break b}}else v=j;while(0);b=v+8|0;d=c[b>>2]|0;x=c[1832]|0;if(v>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=o;c[b>>2]=o;c[m+(p+8)>>2]=d;c[m+(p+12)>>2]=v;c[m+(p+24)>>2]=0;break}else ka()}else{x=n+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}while(0);x=m+8|0;i=L;return x|0}}}else p=-1;while(0);k=c[1830]|0;if(k>>>0>=p>>>0){d=k-p|0;b=c[1833]|0;if(d>>>0>15){c[1833]=b+p;c[1830]=d;c[b+(p+4)>>2]=d|1;c[b+k>>2]=d;c[b+4>>2]=p|3}else{c[1830]=0;c[1833]=0;c[b+4>>2]=k|3;x=b+(k+4)|0;c[x>>2]=c[x>>2]|1}x=b+8|0;i=L;return x|0}k=c[1831]|0;if(k>>>0>p>>>0){w=k-p|0;c[1831]=w;x=c[1834]|0;c[1834]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}do if(!(c[1946]|0)){k=ua(30)|0;if(!(k+-1&k)){c[1948]=k;c[1947]=k;c[1949]=-1;c[1950]=-1;c[1951]=0;c[1939]=0;c[1946]=(ta(0)|0)&-16^1431655768;break}else ka()}while(0);l=p+48|0;g=c[1948]|0;f=p+47|0;h=g+f|0;g=0-g|0;m=h&g;if(m>>>0<=p>>>0){x=0;i=L;return x|0}a=c[1938]|0;if((a|0)!=0?(u=c[1936]|0,v=u+m|0,v>>>0<=u>>>0|v>>>0>a>>>0):0){x=0;i=L;return x|0}d:do if(!(c[1939]&4)){j=c[1834]|0;e:do if(j){a=7760|0;while(1){k=c[a>>2]|0;if(k>>>0<=j>>>0?(s=a+4|0,(k+(c[s>>2]|0)|0)>>>0>j>>>0):0)break;a=c[a+8>>2]|0;if(!a){A=181;break e}}if(a){k=h-(c[1831]|0)&g;if(k>>>0<2147483647){j=ma(k|0)|0;if((j|0)==((c[a>>2]|0)+(c[s>>2]|0)|0))A=190;else A=191}else k=0}else A=181}else A=181;while(0);do if((A|0)==181){j=ma(0)|0;if((j|0)!=(-1|0)){a=j;k=c[1947]|0;h=k+-1|0;if(!(h&a))k=m;else k=m-a+(h+a&0-k)|0;a=c[1936]|0;h=a+k|0;if(k>>>0>p>>>0&k>>>0<2147483647){v=c[1938]|0;if((v|0)!=0?h>>>0<=a>>>0|h>>>0>v>>>0:0){k=0;break}h=ma(k|0)|0;if((h|0)==(j|0))A=190;else{j=h;A=191}}else k=0}else k=0}while(0);f:do if((A|0)==190){if((j|0)!=(-1|0)){w=j;s=k;A=201;break d}}else if((A|0)==191){a=0-k|0;do if((j|0)!=(-1|0)&k>>>0<2147483647&l>>>0>k>>>0?(d=c[1948]|0,d=f-k+d&0-d,d>>>0<2147483647):0)if((ma(d|0)|0)==(-1|0)){ma(a|0)|0;k=0;break f}else{k=d+k|0;break}while(0);if((j|0)==(-1|0))k=0;else{w=j;s=k;A=201;break d}}while(0);c[1939]=c[1939]|4;A=198}else{k=0;A=198}while(0);if((((A|0)==198?m>>>0<2147483647:0)?(w=ma(m|0)|0,x=ma(0)|0,(w|0)!=(-1|0)&(x|0)!=(-1|0)&w>>>0>>0):0)?(z=x-w|0,y=z>>>0>(p+40|0)>>>0,y):0){s=y?z:k;A=201}if((A|0)==201){j=(c[1936]|0)+s|0;c[1936]=j;if(j>>>0>(c[1937]|0)>>>0)c[1937]=j;o=c[1834]|0;g:do if(o){f=7760|0;while(1){k=c[f>>2]|0;g=f+4|0;j=c[g>>2]|0;if((w|0)==(k+j|0)){A=213;break}h=c[f+8>>2]|0;if(!h)break;else f=h}if(((A|0)==213?(c[f+12>>2]&8|0)==0:0)?o>>>0>=k>>>0&o>>>0>>0:0){c[g>>2]=j+s;d=(c[1831]|0)+s|0;b=o+8|0;if(!(b&7))b=0;else b=0-b&7;x=d-b|0;c[1834]=o+b;c[1831]=x;c[o+(b+4)>>2]=x|1;c[o+(d+4)>>2]=40;c[1835]=c[1950];break}k=c[1832]|0;if(w>>>0>>0){c[1832]=w;k=w}h=w+s|0;g=7760|0;while(1){if((c[g>>2]|0)==(h|0)){A=223;break}j=c[g+8>>2]|0;if(!j)break;else g=j}if((A|0)==223?(c[g+12>>2]&8|0)==0:0){c[g>>2]=w;j=g+4|0;c[j>>2]=(c[j>>2]|0)+s;j=w+8|0;if(!(j&7))r=0;else r=0-j&7;j=w+(s+8)|0;if(!(j&7))b=0;else b=0-j&7;j=w+(b+s)|0;q=r+p|0;n=w+q|0;d=j-(w+r)-p|0;c[w+(r+4)>>2]=p|3;h:do if((j|0)!=(o|0)){if((j|0)==(c[1833]|0)){x=(c[1830]|0)+d|0;c[1830]=x;c[1833]=n;c[w+(q+4)>>2]=x|1;c[w+(x+q)>>2]=x;break}l=s+4|0;h=c[w+(l+b)>>2]|0;if((h&3|0)==1){m=h&-8;e=h>>>3;i:do if(h>>>0>=256){a=c[w+((b|24)+s)>>2]|0;g=c[w+(s+12+b)>>2]|0;do if((g|0)==(j|0)){g=b|16;f=w+(l+g)|0;h=c[f>>2]|0;if(!h){g=w+(g+s)|0;h=c[g>>2]|0;if(!h){H=0;break}}else g=f;while(1){e=h+20|0;f=c[e>>2]|0;if(f){h=f;g=e;continue}e=h+16|0;f=c[e>>2]|0;if(!f)break;else{h=f;g=e}}if(g>>>0>>0)ka();else{c[g>>2]=0;H=h;break}}else{f=c[w+((b|8)+s)>>2]|0;if(f>>>0>>0)ka();k=f+12|0;if((c[k>>2]|0)!=(j|0))ka();h=g+8|0;if((c[h>>2]|0)==(j|0)){c[k>>2]=g;c[h>>2]=f;H=g;break}else ka()}while(0);if(!a)break;k=c[w+(s+28+b)>>2]|0;h=7616+(k<<2)|0;do if((j|0)!=(c[h>>2]|0)){if(a>>>0<(c[1832]|0)>>>0)ka();k=a+16|0;if((c[k>>2]|0)==(j|0))c[k>>2]=H;else c[a+20>>2]=H;if(!H)break i}else{c[h>>2]=H;if(H)break;c[1829]=c[1829]&~(1<>>0>>0)ka();c[H+24>>2]=a;j=b|16;k=c[w+(j+s)>>2]|0;do if(k)if(k>>>0>>0)ka();else{c[H+16>>2]=k;c[k+24>>2]=H;break}while(0);j=c[w+(l+j)>>2]|0;if(!j)break;if(j>>>0<(c[1832]|0)>>>0)ka();else{c[H+20>>2]=j;c[j+24>>2]=H;break}}else{g=c[w+((b|8)+s)>>2]|0;f=c[w+(s+12+b)>>2]|0;h=7352+(e<<1<<2)|0;do if((g|0)!=(h|0)){if(g>>>0>>0)ka();if((c[g+12>>2]|0)==(j|0))break;ka()}while(0);if((f|0)==(g|0)){c[1828]=c[1828]&~(1<>>0>>0)ka();k=f+8|0;if((c[k>>2]|0)==(j|0)){D=k;break}ka()}while(0);c[g+12>>2]=f;c[D>>2]=g}while(0);j=w+((m|b)+s)|0;k=m+d|0}else k=d;j=j+4|0;c[j>>2]=c[j>>2]&-2;c[w+(q+4)>>2]=k|1;c[w+(k+q)>>2]=k;j=k>>>3;if(k>>>0<256){g=j<<1;f=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(h>>>0>=(c[1832]|0)>>>0){I=j;J=h;break}ka()}while(0);c[I>>2]=n;c[J+12>>2]=n;c[w+(q+8)>>2]=J;c[w+(q+12)>>2]=f;break}d=k>>>8;do if(!d)f=0;else{if(k>>>0>16777215){f=31;break}v=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|v|f)+(x<>>15)|0;f=k>>>(f+7|0)&1|f<<1}while(0);h=7616+(f<<2)|0;c[w+(q+28)>>2]=f;c[w+(q+20)>>2]=0;c[w+(q+16)>>2]=0;j=c[1829]|0;g=1<>2]=n;c[w+(q+24)>>2]=h;c[w+(q+12)>>2]=n;c[w+(q+8)>>2]=n;break}j=c[h>>2]|0;if((f|0)==31)h=0;else h=25-(f>>>1)|0;j:do if((c[j+4>>2]&-8|0)!=(k|0)){f=k<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(k|0)){K=h;break j}else{f=f<<1;j=h}}if(g>>>0<(c[1832]|0)>>>0)ka();else{c[g>>2]=n;c[w+(q+24)>>2]=j;c[w+(q+12)>>2]=n;c[w+(q+8)>>2]=n;break h}}else K=j;while(0);b=K+8|0;d=c[b>>2]|0;x=c[1832]|0;if(K>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=n;c[b>>2]=n;c[w+(q+8)>>2]=d;c[w+(q+12)>>2]=K;c[w+(q+24)>>2]=0;break}else ka()}else{x=(c[1831]|0)+d|0;c[1831]=x;c[1834]=n;c[w+(q+4)>>2]=x|1}while(0);x=w+(r|8)|0;i=L;return x|0}j=7760|0;while(1){h=c[j>>2]|0;if(h>>>0<=o>>>0?(B=c[j+4>>2]|0,C=h+B|0,C>>>0>o>>>0):0)break;j=c[j+8>>2]|0}j=h+(B+-39)|0;if(!(j&7))j=0;else j=0-j&7;g=h+(B+-47+j)|0;g=g>>>0<(o+16|0)>>>0?o:g;h=g+8|0;j=w+8|0;if(!(j&7))j=0;else j=0-j&7;f=s+-40-j|0;c[1834]=w+j;c[1831]=f;c[w+(j+4)>>2]=f|1;c[w+(s+-36)>>2]=40;c[1835]=c[1950];c[g+4>>2]=27;c[h+0>>2]=c[1940];c[h+4>>2]=c[1941];c[h+8>>2]=c[1942];c[h+12>>2]=c[1943];c[1940]=w;c[1941]=s;c[1943]=0;c[1942]=h;f=g+28|0;c[f>>2]=7;if((g+32|0)>>>0>>0)do{x=f;f=f+4|0;c[f>>2]=7}while((x+8|0)>>>0>>0);if((g|0)!=(o|0)){k=g-o|0;j=o+(k+4)|0;c[j>>2]=c[j>>2]&-2;c[o+4>>2]=k|1;c[o+k>>2]=k;j=k>>>3;if(k>>>0<256){g=j<<1;f=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(b>>>0>=(c[1832]|0)>>>0){E=d;F=b;break}ka()}while(0);c[E>>2]=o;c[F+12>>2]=o;c[o+8>>2]=F;c[o+12>>2]=f;break}d=k>>>8;if(d)if(k>>>0>16777215)g=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;g=14-(v|w|g)+(x<>>15)|0;g=k>>>(g+7|0)&1|g<<1}else g=0;h=7616+(g<<2)|0;c[o+28>>2]=g;c[o+20>>2]=0;c[o+16>>2]=0;e=c[1829]|0;j=1<>2]=o;c[o+24>>2]=h;c[o+12>>2]=o;c[o+8>>2]=o;break}e=c[h>>2]|0;if((g|0)==31)d=0;else d=25-(g>>>1)|0;k:do if((c[e+4>>2]&-8|0)!=(k|0)){j=k<>>31<<2)+16|0;d=c[h>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(k|0)){G=d;break k}else{j=j<<1;e=d}}if(h>>>0<(c[1832]|0)>>>0)ka();else{c[h>>2]=o;c[o+24>>2]=e;c[o+12>>2]=o;c[o+8>>2]=o;break g}}else G=e;while(0);b=G+8|0;d=c[b>>2]|0;x=c[1832]|0;if(G>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=o;c[b>>2]=o;c[o+8>>2]=d;c[o+12>>2]=G;c[o+24>>2]=0;break}else ka()}}else{x=c[1832]|0;if((x|0)==0|w>>>0>>0)c[1832]=w;c[1940]=w;c[1941]=s;c[1943]=0;c[1837]=c[1946];c[1836]=-1;b=0;do{x=b<<1;v=7352+(x<<2)|0;c[7352+(x+3<<2)>>2]=v;c[7352+(x+2<<2)>>2]=v;b=b+1|0}while((b|0)!=32);b=w+8|0;if(!(b&7))b=0;else b=0-b&7;x=s+-40-b|0;c[1834]=w+b;c[1831]=x;c[w+(b+4)>>2]=x|1;c[w+(s+-36)>>2]=40;c[1835]=c[1950]}while(0);b=c[1831]|0;if(b>>>0>p>>>0){w=b-p|0;c[1831]=w;x=c[1834]|0;c[1834]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}}c[(va()|0)>>2]=12;x=0;i=L;return x|0}function kd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=i;if(!a){i=w;return}f=a+-8|0;h=c[1832]|0;if(f>>>0>>0)ka();g=c[a+-4>>2]|0;e=g&3;if((e|0)==1)ka();q=g&-8;r=a+(q+-8)|0;do if(!(g&1)){g=c[f>>2]|0;if(!e){i=w;return}j=-8-g|0;m=a+j|0;n=g+q|0;if(m>>>0>>0)ka();if((m|0)==(c[1833]|0)){f=a+(q+-4)|0;g=c[f>>2]|0;if((g&3|0)!=3){v=m;l=n;break}c[1830]=n;c[f>>2]=g&-2;c[a+(j+4)>>2]=n|1;c[r>>2]=n;i=w;return}d=g>>>3;if(g>>>0<256){e=c[a+(j+8)>>2]|0;f=c[a+(j+12)>>2]|0;g=7352+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0>>0)ka();if((c[e+12>>2]|0)!=(m|0))ka()}if((f|0)==(e|0)){c[1828]=c[1828]&~(1<>>0>>0)ka();g=f+8|0;if((c[g>>2]|0)==(m|0))b=g;else ka()}else b=f+8|0;c[e+12>>2]=f;c[b>>2]=e;v=m;l=n;break}b=c[a+(j+24)>>2]|0;e=c[a+(j+12)>>2]|0;do if((e|0)==(m|0)){f=a+(j+20)|0;g=c[f>>2]|0;if(!g){f=a+(j+16)|0;g=c[f>>2]|0;if(!g){k=0;break}}while(1){d=g+20|0;e=c[d>>2]|0;if(e){g=e;f=d;continue}d=g+16|0;e=c[d>>2]|0;if(!e)break;else{g=e;f=d}}if(f>>>0>>0)ka();else{c[f>>2]=0;k=g;break}}else{d=c[a+(j+8)>>2]|0;if(d>>>0>>0)ka();g=d+12|0;if((c[g>>2]|0)!=(m|0))ka();f=e+8|0;if((c[f>>2]|0)==(m|0)){c[g>>2]=e;c[f>>2]=d;k=e;break}else ka()}while(0);if(b){g=c[a+(j+28)>>2]|0;f=7616+(g<<2)|0;if((m|0)==(c[f>>2]|0)){c[f>>2]=k;if(!k){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();g=b+16|0;if((c[g>>2]|0)==(m|0))c[g>>2]=k;else c[b+20>>2]=k;if(!k){v=m;l=n;break}}f=c[1832]|0;if(k>>>0>>0)ka();c[k+24>>2]=b;g=c[a+(j+16)>>2]|0;do if(g)if(g>>>0>>0)ka();else{c[k+16>>2]=g;c[g+24>>2]=k;break}while(0);g=c[a+(j+20)>>2]|0;if(g)if(g>>>0<(c[1832]|0)>>>0)ka();else{c[k+20>>2]=g;c[g+24>>2]=k;v=m;l=n;break}else{v=m;l=n}}else{v=m;l=n}}else{v=f;l=q}while(0);if(v>>>0>=r>>>0)ka();g=a+(q+-4)|0;f=c[g>>2]|0;if(!(f&1))ka();if(!(f&2)){if((r|0)==(c[1834]|0)){m=(c[1831]|0)+l|0;c[1831]=m;c[1834]=v;c[v+4>>2]=m|1;if((v|0)!=(c[1833]|0)){i=w;return}c[1833]=0;c[1830]=0;i=w;return}if((r|0)==(c[1833]|0)){m=(c[1830]|0)+l|0;c[1830]=m;c[1833]=v;c[v+4>>2]=m|1;c[v+m>>2]=m;i=w;return}h=(f&-8)+l|0;d=f>>>3;do if(f>>>0>=256){b=c[a+(q+16)>>2]|0;g=c[a+(q|4)>>2]|0;do if((g|0)==(r|0)){f=a+(q+12)|0;g=c[f>>2]|0;if(!g){f=a+(q+8)|0;g=c[f>>2]|0;if(!g){p=0;break}}while(1){d=g+20|0;e=c[d>>2]|0;if(e){g=e;f=d;continue}d=g+16|0;e=c[d>>2]|0;if(!e)break;else{g=e;f=d}}if(f>>>0<(c[1832]|0)>>>0)ka();else{c[f>>2]=0;p=g;break}}else{f=c[a+q>>2]|0;if(f>>>0<(c[1832]|0)>>>0)ka();e=f+12|0;if((c[e>>2]|0)!=(r|0))ka();d=g+8|0;if((c[d>>2]|0)==(r|0)){c[e>>2]=g;c[d>>2]=f;p=g;break}else ka()}while(0);if(b){g=c[a+(q+20)>>2]|0;f=7616+(g<<2)|0;if((r|0)==(c[f>>2]|0)){c[f>>2]=p;if(!p){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();g=b+16|0;if((c[g>>2]|0)==(r|0))c[g>>2]=p;else c[b+20>>2]=p;if(!p)break}g=c[1832]|0;if(p>>>0>>0)ka();c[p+24>>2]=b;f=c[a+(q+8)>>2]|0;do if(f)if(f>>>0>>0)ka();else{c[p+16>>2]=f;c[f+24>>2]=p;break}while(0);d=c[a+(q+12)>>2]|0;if(d)if(d>>>0<(c[1832]|0)>>>0)ka();else{c[p+20>>2]=d;c[d+24>>2]=p;break}}}else{e=c[a+q>>2]|0;f=c[a+(q|4)>>2]|0;g=7352+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0<(c[1832]|0)>>>0)ka();if((c[e+12>>2]|0)!=(r|0))ka()}if((f|0)==(e|0)){c[1828]=c[1828]&~(1<>>0<(c[1832]|0)>>>0)ka();g=f+8|0;if((c[g>>2]|0)==(r|0))o=g;else ka()}else o=f+8|0;c[e+12>>2]=f;c[o>>2]=e}while(0);c[v+4>>2]=h|1;c[v+h>>2]=h;if((v|0)==(c[1833]|0)){c[1830]=h;i=w;return}else g=h}else{c[g>>2]=f&-2;c[v+4>>2]=l|1;c[v+l>>2]=l;g=l}e=g>>>3;if(g>>>0<256){f=e<<1;g=7352+(f<<2)|0;d=c[1828]|0;e=1<>2]|0;if(b>>>0<(c[1832]|0)>>>0)ka();else{s=d;t=b}}else{c[1828]=d|e;s=7352+(f+2<<2)|0;t=g}c[s>>2]=v;c[t+12>>2]=v;c[v+8>>2]=t;c[v+12>>2]=g;i=w;return}d=g>>>8;if(d)if(g>>>0>16777215)f=31;else{l=(d+1048320|0)>>>16&8;m=d<>>16&4;m=m<>>16&2;f=14-(k|l|f)+(m<>>15)|0;f=g>>>(f+7|0)&1|f<<1}else f=0;b=7616+(f<<2)|0;c[v+28>>2]=f;c[v+20>>2]=0;c[v+16>>2]=0;d=c[1829]|0;e=1<>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;b:do if((c[b+4>>2]&-8|0)!=(g|0)){f=g<>>31<<2)+16|0;d=c[e>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(g|0)){u=d;break b}else{f=f<<1;b=d}}if(e>>>0<(c[1832]|0)>>>0)ka();else{c[e>>2]=v;c[v+24>>2]=b;c[v+12>>2]=v;c[v+8>>2]=v;break a}}else u=b;while(0);d=u+8|0;b=c[d>>2]|0;m=c[1832]|0;if(u>>>0>=m>>>0&b>>>0>=m>>>0){c[b+12>>2]=v;c[d>>2]=v;c[v+8>>2]=b;c[v+12>>2]=u;c[v+24>>2]=0;break}else ka()}else{c[1829]=d|e;c[b>>2]=v;c[v+24>>2]=b;c[v+12>>2]=v;c[v+8>>2]=v}while(0);m=(c[1836]|0)+-1|0;c[1836]=m;if(!m)b=7768|0;else{i=w;return}while(1){b=c[b>>2]|0;if(!b)break;else b=b+8|0}c[1836]=-1;i=w;return}function ld(){}function md(b){b=b|0;var c=0;c=b;while(a[c>>0]|0)c=c+1|0;return c-b|0}function nd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;h=b&3;i=d|d<<8|d<<16|d<<24;g=f&~3;if(h){h=b+4-h|0;while((b|0)<(h|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(g|0)){c[b>>2]=i;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function od(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return pa(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function pd(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;xa[a&3](b|0,c|0,d|0,e|0,f|0)}function qd(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;_(0)} + +// EMSCRIPTEN_END_FUNCS +var xa=[qd,fc,ec,qd];return{_strlen:md,_free:kd,_broadwayGetMajorVersion:dd,_get_h264bsdClip:Lb,_broadwayExit:cd,_memset:nd,_broadwayCreateStream:Zc,_malloc:jd,_memcpy:od,_broadwayGetMinorVersion:ed,_broadwayPlayStream:$c,_broadwaySetStreamLength:_c,_broadwayInit:ad,runPostSets:ld,stackAlloc:ya,stackSave:za,stackRestore:Aa,setThrew:Ba,setTempRet0:Ea,getTempRet0:Fa,dynCall_viiiii:pd}}) + + +// EMSCRIPTEN_END_ASM +(p.Xc,p.Yc,Q),Bb=p._strlen=$._strlen,Ea=p._free=$._free;p._broadwayGetMajorVersion=$._broadwayGetMajorVersion;p._get_h264bsdClip=$._get_h264bsdClip;p._broadwayExit=$._broadwayExit;var Gb=p._memset=$._memset;p._broadwayCreateStream=$._broadwayCreateStream;var Ca=p._malloc=$._malloc,gc=p._memcpy=$._memcpy; +p._broadwayGetMinorVersion=$._broadwayGetMinorVersion;p._broadwayPlayStream=$._broadwayPlayStream;p._broadwaySetStreamLength=$._broadwaySetStreamLength;p._broadwayInit=$._broadwayInit;p.runPostSets=$.runPostSets;p.dynCall_viiiii=$.dynCall_viiiii;z.pb=$.stackAlloc;z.Tb=$.stackSave;z.Sb=$.stackRestore;z.Yd=$.setTempRet0;z.xd=$.getTempRet0; +if(T)if("function"===typeof p.locateFile?T=p.locateFile(T):p.memoryInitializerPrefixURL&&(T=p.memoryInitializerPrefixURL+T),t||da){var hc=p.readBinary(T);N.set(hc,Ia)}else Ya(),yb(T,function(a){N.set(a,Ia);Za()},function(){d("could not load memory initializer "+T)});function ia(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}ia.prototype=Error();var ic,jc=k,Xa=function kc(){!p.calledRun&&lc&&mc();p.calledRun||(Xa=kc)}; +p.callMain=p.ag=function(a){function b(){for(var a=0;3>a;a++)e.push(0)}w(0==S,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");w(0==Oa.length,"cannot call main when preRun functions remain to be called");a=a||[];Sa||(Sa=i,Na(R));var c=a.length+1,e=[M(Va(p.thisProgram),"i8",0)];b();for(var f=0;f y ? y : z); + } + + function OptimizedGetBoundaryStrengthsA($mb, $bS) { + var $totalCoeff = $mb + 28; + + var tc0 = HEAP16[$totalCoeff + 0 >> 1]; + var tc1 = HEAP16[$totalCoeff + 2 >> 1]; + var tc2 = HEAP16[$totalCoeff + 4 >> 1]; + var tc3 = HEAP16[$totalCoeff + 6 >> 1]; + var tc4 = HEAP16[$totalCoeff + 8 >> 1]; + var tc5 = HEAP16[$totalCoeff + 10 >> 1]; + var tc6 = HEAP16[$totalCoeff + 12 >> 1]; + var tc7 = HEAP16[$totalCoeff + 14 >> 1]; + var tc8 = HEAP16[$totalCoeff + 16 >> 1]; + var tc9 = HEAP16[$totalCoeff + 18 >> 1]; + var tc10 = HEAP16[$totalCoeff + 20 >> 1]; + var tc11 = HEAP16[$totalCoeff + 22 >> 1]; + var tc12 = HEAP16[$totalCoeff + 24 >> 1]; + var tc13 = HEAP16[$totalCoeff + 26 >> 1]; + var tc14 = HEAP16[$totalCoeff + 28 >> 1]; + var tc15 = HEAP16[$totalCoeff + 30 >> 1]; + + HEAP32[$bS + 32 >> 2] = tc2 || tc0 ? 2 : 0; + HEAP32[$bS + 40 >> 2] = tc3 || tc1 ? 2 : 0; + HEAP32[$bS + 48 >> 2] = tc6 || tc4 ? 2 : 0; + HEAP32[$bS + 56 >> 2] = tc7 || tc5 ? 2 : 0; + HEAP32[$bS + 64 >> 2] = tc8 || tc2 ? 2 : 0; + HEAP32[$bS + 72 >> 2] = tc9 || tc3 ? 2 : 0; + HEAP32[$bS + 80 >> 2] = tc12 || tc6 ? 2 : 0; + HEAP32[$bS + 88 >> 2] = tc13 || tc7 ? 2 : 0; + HEAP32[$bS + 96 >> 2] = tc10 || tc8 ? 2 : 0; + HEAP32[$bS + 104 >> 2] = tc11 || tc9 ? 2 : 0; + HEAP32[$bS + 112 >> 2] = tc14 || tc12 ? 2 : 0; + HEAP32[$bS + 120 >> 2] = tc15 || tc13 ? 2 : 0; + + HEAP32[$bS + 12 >> 2] = tc1 || tc0 ? 2 : 0; + HEAP32[$bS + 20 >> 2] = tc4 || tc1 ? 2 : 0; + HEAP32[$bS + 28 >> 2] = tc5 || tc4 ? 2 : 0; + HEAP32[$bS + 44 >> 2] = tc3 || tc2 ? 2 : 0; + HEAP32[$bS + 52 >> 2] = tc6 || tc3 ? 2 : 0; + HEAP32[$bS + 60 >> 2] = tc7 || tc6 ? 2 : 0; + HEAP32[$bS + 76 >> 2] = tc9 || tc8 ? 2 : 0; + HEAP32[$bS + 84 >> 2] = tc12 || tc9 ? 2 : 0; + HEAP32[$bS + 92 >> 2] = tc13 || tc12 ? 2 : 0; + HEAP32[$bS + 108 >> 2] = tc11 || tc10 ? 2 : 0; + HEAP32[$bS + 116 >> 2] = tc14 || tc11 ? 2 : 0; + HEAP32[$bS + 124 >> 2] = tc15 || tc14 ? 2 : 0; + } + + function OptimizedFilterVerLumaEdge ($data, bS, $thresholds, imageWidth) { + var delta, tc, tmp; + var p0, q0, p1, q1, p2, q2; + var tmpFlag; + var $clp = _h264bsdClip + 512; + var alpha = HEAP32[$thresholds + 4 >> 2]; + var beta = HEAP32[$thresholds + 8 >> 2]; + var val; + + if (bS < 4) { + tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255; + for (var i = 4; i > 0; i--) { + p1 = HEAPU8[$data + -2] & 255; + p0 = HEAPU8[$data + -1] & 255; + q0 = HEAPU8[$data] & 255; + q1 = HEAPU8[$data + 1] & 255; + if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) { + p2 = HEAPU8[$data - 3] & 255; + if (Math.abs(p2 - p0) < beta) { + val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; + HEAP8[$data - 2] = p1 + clip(-tc, tc, val); + tmp++; + } + + q2 = HEAPU8[$data + 2] & 255; + if (Math.abs(q2 - q0) < beta) { + val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; + HEAP8[$data + 1] = (q1 + clip(-tc, tc, val)); + tmp++; + } + + val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); + delta = clip(-tmp, tmp, val); + + p0 = HEAPU8[$clp + (p0 + delta)] & 255; + q0 = HEAPU8[$clp + (q0 - delta)] & 255; + tmp = tc; + HEAP8[$data - 1] = p0; + HEAP8[$data] = q0; + + $data += imageWidth; + } + } + } else { + OriginalFilterVerLumaEdge($data, bS, $thresholds, imageWidth); + } + } + + /** + * Filter all four successive horizontal 4-pixel luma edges. This can be done when bS is equal to all four edges. + */ + function OptimizedFilterHorLuma ($data, bS, $thresholds, imageWidth) { + var delta, tc, tmp; + var p0, q0, p1, q1, p2, q2; + var tmpFlag; + var $clp = _h264bsdClip + 512; + var alpha = HEAP32[$thresholds + 4 >> 2]; + var beta = HEAP32[$thresholds + 8 >> 2]; + var val; + + if (bS < 4) { + tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255; + for (var i = 16; i > 0; i--) { + p1 = HEAPU8[$data + (-imageWidth << 1)] & 255; + p0 = HEAPU8[$data + -imageWidth] & 255; + q0 = HEAPU8[$data] & 255; + q1 = HEAPU8[$data + imageWidth] & 255; + + if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) { + p2 = HEAPU8[$data + (-imageWidth * 3)] & 255; + if (Math.abs(p2 - p0) < beta) { + val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; + HEAP8[$data + (-imageWidth << 1)] = p1 + clip(-tc, tc, val); + tmp++; + } + + q2 = HEAPU8[$data + (imageWidth << 2)] & 255; + if (Math.abs(q2 - q0) < beta) { + val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; + HEAP8[$data + imageWidth] = (q1 + clip(-tc, tc, val)); + tmp++; + } + + val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); + delta = clip(-tmp, tmp, val); + + p0 = HEAPU8[$clp + (p0 + delta)] & 255; + q0 = HEAPU8[$clp + (q0 - delta)] & 255; + tmp = tc; + HEAP8[$data - imageWidth] = p0; + HEAP8[$data] = q0; + + $data ++; + } + } + } else { + OriginalFilterHorLuma($data, bS, $thresholds, imageWidth); + } + } + }; + + + Broadway.prototype = { + configure: function (config) { + // patchOptimizations(config, patches); + console.info("Broadway Configured: " + JSON.stringify(config)); + } + + }; + + + + + /* + + asm.js implementation of a yuv to rgb convertor + provided by @soliton4 + + based on + http://www.wordsaretoys.com/2013/10/18/making-yuv-conversion-a-little-faster/ + + */ + + + // factory to create asm.js yuv -> rgb convertor for a given resolution + var asmInstances = {}; + var getAsm = function(parWidth, parHeight){ + var idStr = "" + parWidth + "x" + parHeight; + if (asmInstances[idStr]){ + return asmInstances[idStr]; + }; + + var lumaSize = parWidth * parHeight; + var chromaSize = (lumaSize|0) >> 2; + + var inpSize = lumaSize + chromaSize + chromaSize; + var outSize = parWidth * parHeight * 4; + var cacheSize = Math.pow(2, 24) * 4; + var size = inpSize + outSize + cacheSize; + + var chunkSize = Math.pow(2, 24); + var heapSize = chunkSize; + while (heapSize < size){ + heapSize += chunkSize; + }; + var heap = new ArrayBuffer(heapSize); + + var res = asmFactory(global, {}, heap); + res.init(parWidth, parHeight); + asmInstances[idStr] = res; + + res.heap = heap; + res.out = new Uint8Array(heap, 0, outSize); + res.inp = new Uint8Array(heap, outSize, inpSize); + res.outSize = outSize; + + return res; + }; + + + function asmFactory(stdlib, foreign, heap) { + "use asm"; + + var imul = stdlib.Math.imul; + var min = stdlib.Math.min; + var max = stdlib.Math.max; + var pow = stdlib.Math.pow; + var out = new stdlib.Uint8Array(heap); + var out32 = new stdlib.Uint32Array(heap); + var inp = new stdlib.Uint8Array(heap); + var mem = new stdlib.Uint8Array(heap); + var mem32 = new stdlib.Uint32Array(heap); + + // for double algo + /*var vt = 1.370705; + var gt = 0.698001; + var gt2 = 0.337633; + var bt = 1.732446;*/ + + var width = 0; + var height = 0; + var lumaSize = 0; + var chromaSize = 0; + var inpSize = 0; + var outSize = 0; + + var inpStart = 0; + var outStart = 0; + + var widthFour = 0; + + var cacheStart = 0; + + + function init(parWidth, parHeight){ + parWidth = parWidth|0; + parHeight = parHeight|0; + + var i = 0; + var s = 0; + + width = parWidth; + widthFour = imul(parWidth, 4)|0; + height = parHeight; + lumaSize = imul(width|0, height|0)|0; + chromaSize = (lumaSize|0) >> 2; + outSize = imul(imul(width, height)|0, 4)|0; + inpSize = ((lumaSize + chromaSize)|0 + chromaSize)|0; + + outStart = 0; + inpStart = (outStart + outSize)|0; + cacheStart = (inpStart + inpSize)|0; + + // initializing memory (to be on the safe side) + s = ~~(+pow(+2, +24)); + s = imul(s, 4)|0; + + for (i = 0|0; ((i|0) < (s|0))|0; i = (i + 4)|0){ + mem32[((cacheStart + i)|0) >> 2] = 0; + }; + }; + + function doit(){ + var ystart = 0; + var ustart = 0; + var vstart = 0; + + var y = 0; + var yn = 0; + var u = 0; + var v = 0; + + var o = 0; + + var line = 0; + var col = 0; + + var usave = 0; + var vsave = 0; + + var ostart = 0; + var cacheAdr = 0; + + ostart = outStart|0; + + ystart = inpStart|0; + ustart = (ystart + lumaSize|0)|0; + vstart = (ustart + chromaSize)|0; + + for (line = 0; (line|0) < (height|0); line = (line + 2)|0){ + usave = ustart; + vsave = vstart; + for (col = 0; (col|0) < (width|0); col = (col + 2)|0){ + y = inp[ystart >> 0]|0; + yn = inp[((ystart + width)|0) >> 0]|0; + + u = inp[ustart >> 0]|0; + v = inp[vstart >> 0]|0; + + cacheAdr = (((((y << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(y,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[ostart >> 2] = o; + + cacheAdr = (((((yn << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(yn,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[((ostart + widthFour)|0) >> 2] = o; + + //yuv2rgb5(y, u, v, ostart); + //yuv2rgb5(yn, u, v, (ostart + widthFour)|0); + ostart = (ostart + 4)|0; + + // next step only for y. u and v stay the same + ystart = (ystart + 1)|0; + y = inp[ystart >> 0]|0; + yn = inp[((ystart + width)|0) >> 0]|0; + + //yuv2rgb5(y, u, v, ostart); + cacheAdr = (((((y << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(y,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[ostart >> 2] = o; + + //yuv2rgb5(yn, u, v, (ostart + widthFour)|0); + cacheAdr = (((((yn << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(yn,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[((ostart + widthFour)|0) >> 2] = o; + ostart = (ostart + 4)|0; + + //all positions inc 1 + + ystart = (ystart + 1)|0; + ustart = (ustart + 1)|0; + vstart = (vstart + 1)|0; + }; + ostart = (ostart + widthFour)|0; + ystart = (ystart + width)|0; + + }; + + }; + + function yuv2rgbcalc(y, u, v){ + y = y|0; + u = u|0; + v = v|0; + + var r = 0; + var g = 0; + var b = 0; + + var o = 0; + + var a0 = 0; + var a1 = 0; + var a2 = 0; + var a3 = 0; + var a4 = 0; + + a0 = imul(1192, (y - 16)|0)|0; + a1 = imul(1634, (v - 128)|0)|0; + a2 = imul(832, (v - 128)|0)|0; + a3 = imul(400, (u - 128)|0)|0; + a4 = imul(2066, (u - 128)|0)|0; + + r = (((a0 + a1)|0) >> 10)|0; + g = (((((a0 - a2)|0) - a3)|0) >> 10)|0; + b = (((a0 + a4)|0) >> 10)|0; + + if ((((r & 255)|0) != (r|0))|0){ + r = min(255, max(0, r|0)|0)|0; + }; + if ((((g & 255)|0) != (g|0))|0){ + g = min(255, max(0, g|0)|0)|0; + }; + if ((((b & 255)|0) != (b|0))|0){ + b = min(255, max(0, b|0)|0)|0; + }; + + o = 255; + o = (o << 8)|0; + o = (o + b)|0; + o = (o << 8)|0; + o = (o + g)|0; + o = (o << 8)|0; + o = (o + r)|0; + + return o|0; + + }; + + + + return { + init: init, + doit: doit + }; + }; + + + /* + potential worker initialization + + */ + + + if (typeof self != "undefined"){ + var isWorker = false; + var decoder; + var reuseMemory = false; + + var memAr = []; + var getMem = function(length){ + if (memAr.length){ + var u = memAr.shift(); + while (u && u.byteLength !== length){ + u = memAr.shift(); + }; + if (u){ + return u; + }; + }; + return new ArrayBuffer(length); + }; + + self.addEventListener('message', function(e) { + + if (isWorker){ + if (reuseMemory){ + if (e.data.reuse){ + memAr.push(e.data.reuse); + }; + }; + if (e.data.buf){ + decoder.decode(new Uint8Array(e.data.buf, e.data.offset || 0, e.data.length), e.data.info); + }; + + }else{ + if (e.data && e.data.type === "Broadway.js - Worker init"){ + isWorker = true; + decoder = new Broadway(e.data.options); + + if (e.data.options.reuseMemory){ + reuseMemory = true; + decoder.onPictureDecoded = function (buffer, width, height, infos) { + + //var buf = getMem(); + + // buffer needs to be copied because we give up ownership + var copyU8 = new Uint8Array(getMem(buffer.length)); + copyU8.set( buffer, 0, buffer.length ); + + postMessage({ + buf: copyU8.buffer, + length: buffer.length, + width: width, + height: height, + infos: infos + }, [copyU8.buffer]); // 2nd parameter is used to indicate transfer of ownership + + }; + + }else{ + decoder.onPictureDecoded = function (buffer, width, height, infos) { + if (buffer) { + buffer = new Uint8Array(buffer); + }; + + // buffer needs to be copied because we give up ownership + var copyU8 = new Uint8Array(buffer.length); + copyU8.set( buffer, 0, buffer.length ); + + postMessage({ + buf: copyU8.buffer, + length: buffer.length, + width: width, + height: height, + infos: infos + }, [copyU8.buffer]); // 2nd parameter is used to indicate transfer of ownership + + }; + }; + postMessage({ consoleLog: "broadway worker initialized" }); + }; + }; + + + }, false); + }; + + Broadway.nowValue = nowValue; + + return Broadway; + + })(); + + +})); + diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/FilterWebGLCanvas.js b/tools/ffmpegToWeb/Player/broadway/canvas/FilterWebGLCanvas.js new file mode 100644 index 0000000..a8e380e --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/FilterWebGLCanvas.js @@ -0,0 +1,71 @@ +"use strict"; + +var Class = require('uclass'); + + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", [ + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D FTexture; + + void main(void) { + gl_FragColor = texture2D(FTexture, vTextureCoord); + } +`); + + +var FilterWebGLCanvas = new Class({ + Extends : WebGLCanvas, + + initialize : function(canvas, size, useFrameBuffer) { + FilterWebGLCanvas.parent.initialize.call(this, canvas, size, useFrameBuffer); + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord"); + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + console.log("creatingTextures: size: " + this.size); + this.FTexture = new Texture(this.gl, this.size, this.gl.RGBA); + }, + + onInitSceneTextures: function () { + this.FTexture.bind(0, this.program, "FTexture"); + }, + + process: function(buffer, output) { + this.FTexture.fill(buffer); + this.drawScene(); + this.readPixels(output); + }, + + toString: function() { + return "FilterWebGLCanvas Size: " + this.size; + } +}); + + + +module.exports = FilterWebGLCanvas; + diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/Program.js b/tools/ffmpegToWeb/Player/broadway/canvas/Program.js new file mode 100644 index 0000000..374d315 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/Program.js @@ -0,0 +1,32 @@ +"use strict"; +var assert = require('../utils/assert'); + + +function Program(gl) { + this.gl = gl; + this.program = this.gl.createProgram(); +} + +Program.prototype = { + attach: function (shader) { + this.gl.attachShader(this.program, shader.shader); + }, + link: function () { + this.gl.linkProgram(this.program); + // If creating the shader program failed, alert. + assert(this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS), + "Unable to initialize the shader program."); + }, + use: function () { + this.gl.useProgram(this.program); + }, + getAttributeLocation: function(name) { + return this.gl.getAttribLocation(this.program, name); + }, + setMatrixUniform: function(name, array) { + var uniform = this.gl.getUniformLocation(this.program, name); + this.gl.uniformMatrix4fv(uniform, false, array); + } +}; +module.exports = Program; + diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/README.md b/tools/ffmpegToWeb/Player/broadway/canvas/README.md new file mode 100644 index 0000000..dbb6e85 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/README.md @@ -0,0 +1,4 @@ +/* +* Those files wraps several WebGL constructs and provides a simple, single texture based WebGLCanvas as well as a +* specialized YUVWebGLCanvas that can handle YUV->RGB conversion. +*/ diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/Script.js b/tools/ffmpegToWeb/Player/broadway/canvas/Script.js new file mode 100644 index 0000000..d93416b --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/Script.js @@ -0,0 +1,41 @@ +"use strict"; + +var assert = require('../utils/assert'); + +/** + * Represents a WebGL shader script. + */ + +function Script() {} + +Script.createFromElementId = function(id) { + var script = document.getElementById(id); + + // Didn't find an element with the specified ID, abort. + assert(script , "Could not find shader with ID: " + id); + + // Walk through the source element's children, building the shader source string. + var source = ""; + var currentChild = script .firstChild; + while(currentChild) { + if (currentChild.nodeType == 3) { + source += currentChild.textContent; + } + currentChild = currentChild.nextSibling; + } + + var res = new Scriptor(); + res.type = script.type; + res.source = source; + return res; +}; + +Script.createFromSource = function(type, source) { + var res = new Script(); + res.type = type; + res.source = source; + return res; +} + + +module.exports = Script; \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/Shader.js b/tools/ffmpegToWeb/Player/broadway/canvas/Shader.js new file mode 100644 index 0000000..fecfdfe --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/Shader.js @@ -0,0 +1,38 @@ +"use strict"; + +var error = require('../utils/error'); + +/** + * Represents a WebGL shader object and provides a mechanism to load shaders from HTML + * script tags. + */ + + +function Shader(gl, script) { + + // Now figure out what type of shader script we have, based on its MIME type. + if (script.type == "x-shader/x-fragment") { + this.shader = gl.createShader(gl.FRAGMENT_SHADER); + } else if (script.type == "x-shader/x-vertex") { + this.shader = gl.createShader(gl.VERTEX_SHADER); + } else { + error("Unknown shader type: " + script.type); + return; + } + + // Send the source to the shader object. + gl.shaderSource(this.shader, script.source); + + // Compile the shader program. + gl.compileShader(this.shader); + + // See if it compiled successfully. + if (!gl.getShaderParameter(this.shader, gl.COMPILE_STATUS)) { + error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(this.shader)); + return; + } +} +module.exports = Shader; + + + diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/Texture.js b/tools/ffmpegToWeb/Player/broadway/canvas/Texture.js new file mode 100644 index 0000000..30becff --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/Texture.js @@ -0,0 +1,47 @@ +"use strict"; + +var assert = require('../utils/assert'); + +/** + * Represents a WebGL texture object. + */ + +function Texture(gl, size, format) { + this.gl = gl; + this.size = size; + this.texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + this.format = format ? format : gl.LUMINANCE; + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, size.w, size.h, 0, this.format, gl.UNSIGNED_BYTE, null); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); +} + +var textureIDs = null; +Texture.prototype = { + fill: function(textureData, useTexSubImage2D) { + var gl = this.gl; + assert(textureData.length >= this.size.w * this.size.h, + "Texture size mismatch, data:" + textureData.length + ", texture: " + this.size.w * this.size.h); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + if (useTexSubImage2D) { + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.size.w , this.size.h, this.format, gl.UNSIGNED_BYTE, textureData); + } else { + // texImage2D seems to be faster, thus keeping it as the default + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.size.w, this.size.h, 0, this.format, gl.UNSIGNED_BYTE, textureData); + } + }, + bind: function(n, program, name) { + var gl = this.gl; + if (!textureIDs) { + textureIDs = [gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2]; + } + gl.activeTexture(textureIDs[n]); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.uniform1i(gl.getUniformLocation(program.program, name), n); + } +}; +module.exports = Texture; + diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/WebGLCanvas.js b/tools/ffmpegToWeb/Player/broadway/canvas/WebGLCanvas.js new file mode 100644 index 0000000..65f7210 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/WebGLCanvas.js @@ -0,0 +1,261 @@ +"use strict"; + +/** + * Generic WebGL backed canvas that sets up: a quad to paint a texture on, appropriate vertex/fragment shaders, + * scene parameters and other things. Specialized versions of this class can be created by overriding several + * initialization methods. + + */ + +var Script = require('./Script'); +var error = require('../utils/error'); +var makePerspective = require('../utils/glUtils').makePerspective; +var Matrix = require('sylvester.js').Matrix; +var Class = require('uclass'); + + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", ` + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D texture; + void main(void) { + gl_FragColor = texture2D(texture, vTextureCoord); + } +`); + +var WebGLCanvas = new Class({ + + initialize : function(canvas, size, useFrameBuffer) { + + this.canvas = canvas; + this.size = size; + this.canvas.width = size.w; + this.canvas.height = size.h; + + this.onInitWebGL(); + this.onInitShaders(); + this.initBuffers(); + + if (useFrameBuffer) + this.initFramebuffer(); + + this.onInitTextures(); + this.initScene(); + }, + + +/** + * Initialize a frame buffer so that we can render off-screen. + */ + initFramebuffer : function() { + + var gl = this.gl; + + // Create framebuffer object and texture. + this.framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + this.framebufferTexture = new Texture(this.gl, this.size, gl.RGBA); + + // Create and allocate renderbuffer for depth data. + var renderbuffer = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.size.w, this.size.h); + + // Attach texture and renderbuffer to the framebuffer. + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.framebufferTexture.texture, 0); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer); + }, + + + +/** + * Initialize vertex and texture coordinate buffers for a plane. + */ + initBuffers : function () { + var tmp; + var gl = this.gl; + + // Create vertex position buffer. + this.quadVPBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer); + tmp = [ + 1.0, 1.0, 0.0, + -1.0, 1.0, 0.0, + 1.0, -1.0, 0.0, + -1.0, -1.0, 0.0]; + + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW); + this.quadVPBuffer.itemSize = 3; + this.quadVPBuffer.numItems = 4; + + /* + +--------------------+ + | -1,1 (1) | 1,1 (0) + | | + | | + | | + | | + | | + | -1,-1 (3) | 1,-1 (2) + +--------------------+ + */ + + var scaleX = 1.0; + var scaleY = 1.0; + + // Create vertex texture coordinate buffer. + this.quadVTCBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer); + tmp = [ + scaleX, 0.0, + 0.0, 0.0, + scaleX, scaleY, + 0.0, scaleY, + ]; + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW); + }, + + + mvIdentity : function () { + this.mvMatrix = Matrix.I(4); + }, + + mvMultiply : function(m) { + this.mvMatrix = this.mvMatrix.x(m); + }, + + mvTranslate : function (m) { + this.mvMultiply(Matrix.Translation($V([m[0], m[1], m[2]])).ensure4x4()); + }, + + setMatrixUniforms : function () { + this.program.setMatrixUniform("uPMatrix", new Float32Array(this.perspectiveMatrix.flatten())); + this.program.setMatrixUniform("uMVMatrix", new Float32Array(this.mvMatrix.flatten())); + }, + + initScene : function() { + var gl = this.gl; + + // Establish the perspective with which we want to view the + // scene. Our field of view is 45 degrees, with a width/height + // ratio of 640:480, and we only want to see objects between 0.1 units + // and 100 units away from the camera. + + this.perspectiveMatrix = makePerspective(45, 1, 0.1, 100.0); + + // Set the drawing position to the "identity" point, which is + // the center of the scene. + this.mvIdentity(); + + // Now move the drawing position a bit to where we want to start + // drawing the square. + this.mvTranslate([0.0, 0.0, -2.4]); + + // Draw the cube by binding the array buffer to the cube's vertices + // array, setting attributes, and pushing it to GL. + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer); + gl.vertexAttribPointer(this.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); + + // Set the texture coordinates attribute for the vertices. + + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer); + gl.vertexAttribPointer(this.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + + this.onInitSceneTextures(); + + this.setMatrixUniforms(); + + if (this.framebuffer) { + console.log("Bound Frame Buffer"); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + } + }, + + + + toString: function() { + return "WebGLCanvas Size: " + this.size; + }, + + checkLastError: function (operation) { + var err = this.gl.getError(); + if (err != this.gl.NO_ERROR) { + var name = this.glNames[err]; + name = (name !== undefined) ? name + "(" + err + ")": + ("Unknown WebGL ENUM (0x" + value.toString(16) + ")"); + if (operation) { + console.log("WebGL Error: %s, %s", operation, name); + } else { + console.log("WebGL Error: %s", name); + } + console.trace(); + } + }, + + onInitWebGL: function () { + try { + this.gl = this.canvas.getContext("experimental-webgl"); + } catch(e) {} + + if (!this.gl) { + error("Unable to initialize WebGL. Your browser may not support it."); + } + if (this.glNames) { + return; + } + this.glNames = {}; + for (var propertyName in this.gl) { + if (typeof this.gl[propertyName] == 'number') { + this.glNames[this.gl[propertyName]] = propertyName; + } + } + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");; + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + var gl = this.gl; + this.texture = new Texture(gl, this.size, gl.RGBA); + }, + + onInitSceneTextures: function () { + this.texture.bind(0, this.program, "texture"); + }, + + drawScene: function() { + this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); + }, + + readPixels: function(buffer) { + var gl = this.gl; + gl.readPixels(0, 0, this.size.w, this.size.h, gl.RGBA, gl.UNSIGNED_BYTE, buffer); + }, + + +}); + + + +module.exports = WebGLCanvas; diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/YUVCanvas.js b/tools/ffmpegToWeb/Player/broadway/canvas/YUVCanvas.js new file mode 100644 index 0000000..326135f --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/YUVCanvas.js @@ -0,0 +1,51 @@ +"use strict"; +var Class = require('uclass'); + +var YUVCanvas = new Class({ + + Binds : ['decode'], + + initialize : function(canvas, size) { + this.canvas = canvas; + this.canvasCtx = this.canvas.getContext("2d"); + this.canvasBuffer = this.canvasCtx.createImageData(size.w, size.h); + }, + + decode : function (buffer, width, height) { + if (!buffer) + return; + + var lumaSize = width * height; + var chromaSize = lumaSize >> 2; + + var ybuf = buffer.subarray(0, lumaSize); + var ubuf = buffer.subarray(lumaSize, lumaSize + chromaSize); + var vbuf = buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize); + + for (var y = 0; y < height; y++) { + for (var x = 0; x < width; x++) { + var yIndex = x + y * width; + var uIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2); + var vIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2); + var R = 1.164 * (ybuf[yIndex] - 16) + 1.596 * (vbuf[vIndex] - 128); + var G = 1.164 * (ybuf[yIndex] - 16) - 0.813 * (vbuf[vIndex] - 128) - 0.391 * (ubuf[uIndex] - 128); + var B = 1.164 * (ybuf[yIndex] - 16) + 2.018 * (ubuf[uIndex] - 128); + + var rgbIndex = yIndex * 4; + this.canvasBuffer.data[rgbIndex+0] = R; + this.canvasBuffer.data[rgbIndex+1] = G; + this.canvasBuffer.data[rgbIndex+2] = B; + this.canvasBuffer.data[rgbIndex+3] = 0xff; + } + } + + this.canvasCtx.putImageData(this.canvasBuffer, 0, 0); + + var date = new Date(); + //console.log("WSAvcPlayer: Decode time: " + (date.getTime() - this.rcvtime) + " ms"); + }, + +}); + + +module.exports = YUVCanvas; \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/canvas/YUVWebGLCanvas.js b/tools/ffmpegToWeb/Player/broadway/canvas/YUVWebGLCanvas.js new file mode 100644 index 0000000..0280670 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/canvas/YUVWebGLCanvas.js @@ -0,0 +1,108 @@ +"use strict"; + +var Program = require('./Program'); +var Shader = require('./Shader'); +var Texture = require('./Texture'); +var Script = require('./Script'); +var WebGLCanvas = require('./WebGLCanvas'); + +var Class = require('uclass'); + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", ` + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D YTexture; + uniform sampler2D UTexture; + uniform sampler2D VTexture; + const mat4 YUV2RGB = mat4 + ( + 1.1643828125, 0, 1.59602734375, -.87078515625, + 1.1643828125, -.39176171875, -.81296875, .52959375, + 1.1643828125, 2.017234375, 0, -1.081390625, + 0, 0, 0, 1 + ); + + void main(void) { + gl_FragColor = vec4( texture2D(YTexture, vTextureCoord).x, texture2D(UTexture, vTextureCoord).x, texture2D(VTexture, vTextureCoord).x, 1) * YUV2RGB; + } +`); + + + + +var YUVWebGLCanvas = new Class({ + Extends : WebGLCanvas, + Binds : ['decode'], + + initialize : function(canvas, size) { + YUVWebGLCanvas.parent.initialize.call(this, canvas, size); + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");; + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + console.log("creatingTextures: size: " + this.size); + this.YTexture = new Texture(this.gl, this.size); + this.UTexture = new Texture(this.gl, this.size.getHalfSize()); + this.VTexture = new Texture(this.gl, this.size.getHalfSize()); + }, + + onInitSceneTextures: function () { + this.YTexture.bind(0, this.program, "YTexture"); + this.UTexture.bind(1, this.program, "UTexture"); + this.VTexture.bind(2, this.program, "VTexture"); + }, + + fillYUVTextures: function(y, u, v) { + this.YTexture.fill(y); + this.UTexture.fill(u); + this.VTexture.fill(v); + }, + + decode: function(buffer, width, height) { + + if (!buffer) + return; + + var lumaSize = width * height; + var chromaSize = lumaSize >> 2; + + this.YTexture.fill(buffer.subarray(0, lumaSize)); + this.UTexture.fill(buffer.subarray(lumaSize, lumaSize + chromaSize)); + this.VTexture.fill(buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize)); + this.drawScene(); + }, + + toString: function() { + return "YUVCanvas Size: " + this.size; + } +}); + + + + + +module.exports = YUVWebGLCanvas; diff --git a/tools/ffmpegToWeb/Player/broadway/dist/http-live-player.js b/tools/ffmpegToWeb/Player/broadway/dist/http-live-player.js new file mode 100644 index 0000000..f8b3e31 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/dist/http-live-player.js @@ -0,0 +1,5214 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.WSAvcPlayer = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +function useColors() { + // is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + return (typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style) || + // is firebug? http://stackoverflow.com/a/398120/376773 + (window.console && (console.firebug || (console.exception && console.table))) || + // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); +} + +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +exports.formatters.j = function(v) { + return JSON.stringify(v); +}; + + +/** + * Colorize log arguments if enabled. + * + * @api public + */ + +function formatArgs() { + var args = arguments; + var useColors = this.useColors; + + args[0] = (useColors ? '%c' : '') + + this.namespace + + (useColors ? ' %c' : ' ') + + args[0] + + (useColors ? '%c ' : ' ') + + '+' + exports.humanize(this.diff); + + if (!useColors) return args; + + var c = 'color: ' + this.color; + args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); + + // the final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + var index = 0; + var lastC = 0; + args[0].replace(/%[a-z%]/g, function(match) { + if ('%%' === match) return; + index++; + if ('%c' === match) { + // we only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + + args.splice(lastC, 0, c); + return args; +} + +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". + * + * @api public + */ + +function log() { + // this hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return 'object' === typeof console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + +function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch(e) {} +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + var r; + try { + r = exports.storage.debug; + } catch(e) {} + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if ('env' in (typeof process === 'undefined' ? {} : process)) { + r = process.env.DEBUG; + } + + return r; +} + +/** + * Enable namespaces listed in `localStorage.debug` initially. + */ + +exports.enable(load()); + +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + +function localstorage(){ + try { + return window.localStorage; + } catch (e) {} +} + +},{"./debug":2}],2:[function(require,module,exports){ + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = debug.debug = debug; +exports.coerce = coerce; +exports.disable = disable; +exports.enable = enable; +exports.enabled = enabled; +exports.humanize = require('ms'); + +/** + * The currently active debug mode names, and names to skip. + */ + +exports.names = []; +exports.skips = []; + +/** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lowercased letter, i.e. "n". + */ + +exports.formatters = {}; + +/** + * Previously assigned color. + */ + +var prevColor = 0; + +/** + * Previous log timestamp. + */ + +var prevTime; + +/** + * Select a color. + * + * @return {Number} + * @api private + */ + +function selectColor() { + return exports.colors[prevColor++ % exports.colors.length]; +} + +/** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + +function debug(namespace) { + + // define the `disabled` version + function disabled() { + } + disabled.enabled = false; + + // define the `enabled` version + function enabled() { + + var self = enabled; + + // set `diff` timestamp + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + + // add the `color` if not set + if (null == self.useColors) self.useColors = exports.useColors(); + if (null == self.color && self.useColors) self.color = selectColor(); + + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + + args[0] = exports.coerce(args[0]); + + if ('string' !== typeof args[0]) { + // anything else let's inspect with %o + args = ['%o'].concat(args); + } + + // apply any `formatters` transformations + var index = 0; + args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { + // if we encounter an escaped % then don't increase the array index + if (match === '%%') return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); + + // now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + // apply env-specific formatting + args = exports.formatArgs.apply(self, args); + + var logFn = enabled.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } + enabled.enabled = true; + + var fn = exports.enabled(namespace) ? enabled : disabled; + + fn.namespace = namespace; + + return fn; +} + +/** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + +function enable(namespaces) { + exports.save(namespaces); + + var split = (namespaces || '').split(/[\s,]+/); + var len = split.length; + + for (var i = 0; i < len; i++) { + if (!split[i]) continue; // ignore empty strings + namespaces = split[i].replace(/[\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } + } +} + +/** + * Disable debug output. + * + * @api public + */ + +function disable() { + exports.enable(''); +} + +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + +function enabled(name) { + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; +} + +/** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} + +},{"ms":3}],3:[function(require,module,exports){ +/** + * Helpers. + */ + +var s = 1000 +var m = s * 60 +var h = m * 60 +var d = h * 24 +var y = d * 365.25 + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} options + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ + +module.exports = function (val, options) { + options = options || {} + var type = typeof val + if (type === 'string' && val.length > 0) { + return parse(val) + } else if (type === 'number' && isNaN(val) === false) { + return options.long ? + fmtLong(val) : + fmtShort(val) + } + throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val)) +} + +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function parse(str) { + str = String(str) + if (str.length > 10000) { + return + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str) + if (!match) { + return + } + var n = parseFloat(match[1]) + var type = (match[2] || 'ms').toLowerCase() + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y + case 'days': + case 'day': + case 'd': + return n * d + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n + default: + return undefined + } +} + +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd' + } + if (ms >= h) { + return Math.round(ms / h) + 'h' + } + if (ms >= m) { + return Math.round(ms / m) + 'm' + } + if (ms >= s) { + return Math.round(ms / s) + 's' + } + return ms + 'ms' +} + +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtLong(ms) { + return plural(ms, d, 'day') || + plural(ms, h, 'hour') || + plural(ms, m, 'minute') || + plural(ms, s, 'second') || + ms + ' ms' +} + +/** + * Pluralization helper. + */ + +function plural(ms, n, name) { + if (ms < n) { + return + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name + } + return Math.ceil(ms / n) + ' ' + name + 's' +} + +},{}],4:[function(require,module,exports){ +(function (__dirname){ +// universal module definition +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], factory); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.Decoder = factory(); + } +}(this, function () { + + var global; + + function initglobal(){ + global = this; + if (!global){ + if (typeof window != "undefined"){ + global = window; + }else if (typeof self != "undefined"){ + global = self; + }; + }; + }; + initglobal(); + + + function error(message) { + console.error(message); + console.trace(); + }; + + + function assert(condition, message) { + if (!condition) { + error(message); + }; + }; + + + return (function(){ + "use strict"; + + + + + var getModule = function(_broadwayOnHeadersDecoded, _broadwayOnPictureDecoded){ + + var window = this; + //console.log(typeof window); + + window._broadwayOnHeadersDecoded = _broadwayOnHeadersDecoded; + window._broadwayOnPictureDecoded = _broadwayOnPictureDecoded; + + var Module = { + 'print': function(text) { console.log('stdout: ' + text); }, + 'printErr': function(text) { console.log('stderr: ' + text); } + }; + + + /* + + The reason why this is all packed into one file is that this file can also function as worker. + you can integrate the file into your build system and provide the original file to be loaded into a worker. + + */ + +function d(a){throw a;}var g=void 0,i=!0,k=null,m=!1;function n(){return function(){}}var p;p||(p=eval("(function() { try { return Module || {} } catch(e) { return {} } })()"));var aa={},r;for(r in p)p.hasOwnProperty(r)&&(aa[r]=p[r]);var t="object"===typeof process&&"function"===typeof null,ba="object"===typeof window,ca="function"===typeof importScripts,da=!ba&&!t&&!ca; +if(t){p.print||(p.print=function(a){process.stdout.write(a+"\n")});p.printErr||(p.printErr=function(a){process.stderr.write(a+"\n")});var fa=(null)("fs"),ga=(null)("path");p.read=function(a,b){var a=ga.normalize(a),c=fa.readFileSync(a);!c&&a!=ga.resolve(a)&&(a=path.join(__dirname,"..","src",a),c=fa.readFileSync(a));c&&!b&&(c=c.toString());return c};p.readBinary=function(a){return p.read(a,i)};p.load=function(a){ha(read(a))};p.thisProgram=1 0) var gc = undefined")):ba||ca?(p.read=function(a){var b=new XMLHttpRequest;b.open("GET",a,m);b.send(k);return b.responseText},"undefined"!=typeof arguments&&(p.arguments=arguments),"undefined"!==typeof console?(p.print||(p.print=function(a){console.log(a)}),p.printErr||(p.printErr=function(a){console.log(a)})):p.print||(p.print= +n()),ba?window.Module=p:p.load=importScripts):d("Unknown runtime environment. Where are we?");function ha(a){eval.call(k,a)}!p.load&&p.read&&(p.load=function(a){ha(p.read(a))});p.print||(p.print=n());p.printErr||(p.printErr=p.print);p.arguments||(p.arguments=[]);p.thisProgram||(p.thisProgram="./this.program");p.print=p.print;p.fa=p.printErr;p.preRun=[];p.postRun=[];for(r in aa)aa.hasOwnProperty(r)&&(p[r]=aa[r]); +var z={Yd:function(a){ja=a},xd:function(){return ja},Tb:function(){return y},Sb:function(a){y=a},oc:function(a){switch(a){case "i1":case "i8":return 1;case "i16":return 2;case "i32":return 4;case "i64":return 8;case "float":return 4;case "double":return 8;default:return"*"===a[a.length-1]?z.ia:"i"===a[0]?(a=parseInt(a.substr(1)),w(0===a%8),a/8):0}},vd:function(a){return Math.max(z.oc(a),z.ia)},Qf:16,ng:function(a,b,c){return!c&&("i64"==a||"double"==a)?8:!a?Math.min(b,8):Math.min(b||(a?z.vd(a):0), +z.ia)},Fa:function(a,b,c){return c&&c.length?(c.splice||(c=Array.prototype.slice.call(c)),c.splice(0,0,b),p["dynCall_"+a].apply(k,c)):p["dynCall_"+a].call(k,b)},eb:[],Vc:function(a){for(var b=0;b=F&&A("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+F+", (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.");return b},ub:function(a,b){return Math.ceil(a/(b?b:16))*(b?b:16)},Fg:function(a,b,c){return c?+(a>>>0)+4294967296*+(b>>>0):+(a>>>0)+4294967296* ++(b|0)},Pc:8,ia:4,Rf:0};p.Runtime=z;z.addFunction=z.Vc;z.removeFunction=z.Sd;var H=m,la,ma,ja;function w(a,b){a||A("Assertion failed: "+b)}function na(a){var b=p["_"+a];if(!b)try{b=eval("_"+a)}catch(c){}w(b,"Cannot call unknown function "+a+" (perhaps LLVM optimizations or closure removed it?)");return b}var oa,pa; +(function(){function a(a){a=a.toString().match(e).slice(1);return{arguments:a[0],body:a[1],returnValue:a[2]}}var b={stackSave:function(){z.Tb()},stackRestore:function(){z.Sb()},arrayToC:function(a){var b=z.pb(a.length);qa(a,b);return b},stringToC:function(a){var b=0;a!==k&&(a!==g&&0!==a)&&(b=z.pb((a.length<<2)+1),ra(a,b));return b}},c={string:b.stringToC,array:b.arrayToC};pa=function(a,b,e,f){var h=na(a),s=[],a=0;if(f)for(var v=0;v>0]=b;break;case "i8":I[a>>0]=b;break;case "i16":J[a>>1]=b;break;case "i32":K[a>>2]=b;break;case "i64":ma=[b>>>0,(la=b,1<=+ta(la)?0>>0:~~+xa((la-+(~~la>>>0))/4294967296)>>>0:0)];K[a>>2]=ma[0];K[a+4>>2]=ma[1];break;case "float":ya[a>>2]=b;break;case "double":za[a>>3]=b;break;default:A("invalid type for setValue: "+c)}}p.setValue=sa; +function Aa(a,b){b=b||"i8";"*"===b.charAt(b.length-1)&&(b="i32");switch(b){case "i1":return I[a>>0];case "i8":return I[a>>0];case "i16":return J[a>>1];case "i32":return K[a>>2];case "i64":return K[a>>2];case "float":return ya[a>>2];case "double":return za[a>>3];default:A("invalid type for setValue: "+b)}return k}p.getValue=Aa;var L=2,Ba=4;p.ALLOC_NORMAL=0;p.ALLOC_STACK=1;p.ALLOC_STATIC=L;p.ALLOC_DYNAMIC=3;p.ALLOC_NONE=Ba; +function M(a,b,c,e){var f,h;"number"===typeof a?(f=i,h=a):(f=m,h=a.length);var j="string"===typeof b?b:k,c=c==Ba?e:[Ca,z.pb,z.Ec,z.bb][c===g?L:c](Math.max(h,j?1:b.length));if(f){e=c;w(0==(c&3));for(a=c+(h&-4);e>2]=0;for(a=c+h;e>0]=0;return c}if("i8"===j)return a.subarray||a.slice?N.set(a,c):N.set(new Uint8Array(a),c),c;for(var e=0,l,u;e>0];if(128<=e)c=i;else if(0==e&&!b)break;f++;if(b&&f==b)break}b||(b=f);var h="";if(!c){for(;0>0],h+=c.nb(e);return h}p.Pointer_stringify=ka;p.UTF16ToString=function(a){for(var b=0,c="";;){var e=J[a+2*b>>1];if(0==e)return c;++b;c+=String.fromCharCode(e)}}; +p.stringToUTF16=function(a,b){for(var c=0;c>1]=a.charCodeAt(c);J[b+2*a.length>>1]=0};p.UTF32ToString=function(a){for(var b=0,c="";;){var e=K[a+4*b>>2];if(0==e)return c;++b;65536<=e?(e-=65536,c+=String.fromCharCode(55296|e>>10,56320|e&1023)):c+=String.fromCharCode(e)}};p.stringToUTF32=function(a,b){for(var c=0,e=0;e=f)var h=a.charCodeAt(++e),f=65536+((f&1023)<<10)|h&1023;K[b+4*c>>2]=f;++c}K[b+4*c>>2]=0}; +function Da(a){function b(c,e,f){var e=e||Infinity,h="",j=[],s;if("N"===a[l]){l++;"K"===a[l]&&l++;for(s=[];"E"!==a[l];)if("S"===a[l]){l++;var C=a.indexOf("_",l);s.push(q[a.substring(l,C)||0]||"?");l=C+1}else if("C"===a[l])s.push(s[s.length-1]),l+=2;else{var C=parseInt(a.substr(l)),P=C.toString().length;if(!C||!P){l--;break}var sb=a.substr(l+P,C);s.push(sb);q.push(sb);l+=P+C}l++;s=s.join("::");e--;if(0===e)return c?[s]:s}else if(("K"===a[l]||x&&"L"===a[l])&&l++,C=parseInt(a.substr(l)))P=C.toString().length, +s=a.substr(l+P,C),l+=P+C;x=m;"I"===a[l]?(l++,C=b(i),P=b(i,1,i),h+=P[0]+" "+s+"<"+C.join(", ")+">"):h=s;a:for(;lO?2*O:O+16777216; +O!==F&&(p.fa("increasing TOTAL_MEMORY to "+O+" to be compliant with the asm.js spec"),F=O);w("undefined"!==typeof Int32Array&&"undefined"!==typeof Float64Array&&!!(new Int32Array(1)).subarray&&!!(new Int32Array(1)).set,"JS engine does not provide full typed array support");var Q=new ArrayBuffer(F);I=new Int8Array(Q);J=new Int16Array(Q);K=new Int32Array(Q);N=new Uint8Array(Q);Ga=new Uint16Array(Q);Ha=new Uint32Array(Q);ya=new Float32Array(Q);za=new Float64Array(Q);K[0]=255;w(255===N[0]&&0===N[3],"Typed arrays 2 must be run on a little-endian system"); +p.HEAP=g;p.buffer=Q;p.HEAP8=I;p.HEAP16=J;p.HEAP32=K;p.HEAPU8=N;p.HEAPU16=Ga;p.HEAPU32=Ha;p.HEAPF32=ya;p.HEAPF64=za;function Na(a){for(;0>0]=a[c],c+=1}p.writeStringToMemory=ra;function qa(a,b){for(var c=0;c>0]=a[c]}p.writeArrayToMemory=qa; +p.writeAsciiToMemory=function(a,b,c){for(var e=0;e>0]=a.charCodeAt(e);c||(I[b+a.length>>0]=0)};if(!Math.imul||-5!==Math.imul(4294967295,5))Math.imul=function(a,b){var c=a&65535,e=b&65535;return c*e+((a>>>16)*e+c*(b>>>16)<<16)|0};Math.vg=Math.imul;var ta=Math.abs,xa=Math.ceil,wa=Math.floor,va=Math.min,S=0,Wa=k,Xa=k;function Ya(){S++;p.monitorRunDependencies&&p.monitorRunDependencies(S)}p.addRunDependency=Ya; +function Za(){S--;p.monitorRunDependencies&&p.monitorRunDependencies(S);if(0==S&&(Wa!==k&&(clearInterval(Wa),Wa=k),Xa)){var a=Xa;Xa=k;a()}}p.removeRunDependency=Za;p.preloadedImages={};p.preloadedAudios={};var T=k,Ia=8,D=Ia+7808;R.push(); +M([0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,0,0,0,0,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,0,0,0,0,10,0,0,0,13,0,0,0,16,0,0,0,11,0,0,0,14,0,0,0,18,0,0,0,13,0,0,0,16,0,0,0,20,0,0,0,14,0,0,0,18,0,0,0,23,0,0,0,16,0,0,0,20,0,0,0,25,0,0,0,18,0,0,0,23,0,0,0,29,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0, +0,0,14,0,0,0,15,0,0,0,16,0,0,0,17,0,0,0,18,0,0,0,19,0,0,0,20,0,0,0,21,0,0,0,22,0,0,0,23,0,0,0,24,0,0,0,25,0,0,0,26,0,0,0,27,0,0,0,28,0,0,0,29,0,0,0,29,0,0,0,30,0,0,0,31,0,0,0,32,0,0,0,32,0,0,0,33,0,0,0,34,0,0,0,34,0,0,0,35,0,0,0,35,0,0,0,36,0,0,0,36,0,0,0,37,0,0,0,37,0,0,0,37,0,0,0,38,0,0,0,38,0,0,0,38,0,0,0,39,0,0,0,39,0,0,0,39,0,0,0,39,0,0,0,1,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,16,0,0,0,32,0,0,0,64,0,0,0,128,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,1,0,0,0,4,0,0, +0,5,0,0,0,2,0,0,0,3,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,12,0,0,0,13,0,0,0,10,0,0,0,11,0,0,0,14,0,0,0,15,0,0,0,47,31,15,0,23,27,29,30,7,11,13,14,39,43,45,46,16,3,5,10,12,19,21,26,28,35,37,42,44,1,2,4,8,17,18,20,24,6,9,22,25,32,33,34,36,40,38,41,0,16,1,2,4,8,32,3,5,10,12,15,47,7,11,13,14,6,9,31,35,37,42,44,33,34,36,40,39,43,45,46,17,18,20,24,19,21,26,28,23,27,29,30,22,25,38,41,17,1,0,0,0,0,0,0,34,18,1,1,0,0,0,0,50,34,18,2,0,0,0,0,67,51,34,34,18,18,2,2,83,67,51,35,18,18,2,2,19,35,67,51,99,83,2,2,0, +0,101,85,68,68,52,52,35,35,35,35,19,19,19,19,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,249,233,217,200,200,184,184,167,167,167,167,151,151,151,151,134,134,134,134,134,134,134,134,118,118,118,118,118,118,118,118,230,214,198,182,165,165,149,149,132,132,132,132,116,116,116,116,100,100,100,100,84,84,84,84,67,67,67,67,67,67,67,67,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,19,19,19,19,19,19,19,19,3,3,3,3,3,3,3,3,214,182,197,197,165,165,149,149,132,132,132,132,84,84,84,84,68,68,68,68,4,4,4,4,115,115,115,115, +115,115,115,115,99,99,99,99,99,99,99,99,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,19,19,19,19,19,19,19,19,197,181,165,5,148,148,116,116,52,52,36,36,131,131,131,131,99,99,99,99,83,83,83,83,67,67,67,67,19,19,19,19,181,149,164,164,132,132,36,36,20,20,4,4,115,115,115,115,99,99,99,99,83,83,83,83,67,67,67,67,51,51,51,51,166,6,21,21,132,132,132,132,147,147,147,147,147,147,147,147,115,115,115,115,115,115,115,115,99,99,99,99,99,99,99,99,83,83,83,83,83,83,83,83,67,67,67,67,67,67,67,67,51,51,51,51,51, +51,51,51,35,35,35,35,35,35,35,35,150,6,21,21,116,116,116,116,131,131,131,131,131,131,131,131,99,99,99,99,99,99,99,99,67,67,67,67,67,67,67,67,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,134,6,37,37,20,20,20,20,115,115,115,115,115,115,115,115,99,99,99,99,99,99,99,99,51,51,51,51,51,51,51,51,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,22,6,117,117,36,36,36,36,83,83,83,83,83,83,83,83,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,21,5,100,100,35,35,35,35,82,82,82,82,82,82,82,82,66,66,66,66,66,66,66,66,50,50,50,50,50,50,50,50,4,20,35,35,51,51,83,83,65,65,65,65,65,65,65,65,4,20,67,67,34,34,34,34,49,49,49,49,49,49,49,49,3,19,50,50,33,33,33,33,2,18,33,33,0,0,0,0,0,0,0,0,0,0,102,32,38,16,6,8,101,24,101,24,67,16,67,16,67,16,67,16,67,16,67,16,67,16,67,16,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34, +8,34,8,34,8,34,8,34,8,34,8,34,8,0,0,0,0,0,0,0,0,106,64,74,48,42,40,10,32,105,56,105,56,73,40,73,40,41,32,41,32,9,24,9,24,104,48,104,48,104,48,104,48,72,32,72,32,72,32,72,32,40,24,40,24,40,24,40,24,8,16,8,16,8,16,8,16,103,40,103,40,103,40,103,40,103,40,103,40,103,40,103,40,71,24,71,24,71,24,71,24,71,24,71,24,71,24,71,24,110,96,78,88,46,80,14,80,110,88,78,80,46,72,14,72,13,64,13,64,77,72,77,72,45,64,45,64,13,56,13,56,109,80,109,80,77,64,77,64,45,56,45,56,13,48,13,48,107,72,107,72,107,72,107,72,107, +72,107,72,107,72,107,72,75,56,75,56,75,56,75,56,75,56,75,56,75,56,75,56,43,48,43,48,43,48,43,48,43,48,43,48,43,48,43,48,11,40,11,40,11,40,11,40,11,40,11,40,11,40,11,40,0,0,0,0,47,104,47,104,16,128,80,128,48,128,16,120,112,128,80,120,48,120,16,112,112,120,80,112,48,112,16,104,111,112,111,112,79,104,79,104,47,96,47,96,15,96,15,96,111,104,111,104,79,96,79,96,47,88,47,88,15,88,15,88,0,0,0,0,0,0,0,0,102,56,70,32,38,32,6,16,102,48,70,24,38,24,6,8,101,40,101,40,37,16,37,16,100,32,100,32,100,32,100,32,100, +24,100,24,100,24,100,24,67,16,67,16,67,16,67,16,67,16,67,16,67,16,67,16,0,0,0,0,0,0,0,0,105,72,73,56,41,56,9,48,8,40,8,40,72,48,72,48,40,48,40,48,8,32,8,32,103,64,103,64,103,64,103,64,71,40,71,40,71,40,71,40,39,40,39,40,39,40,39,40,7,24,7,24,7,24,7,24,0,0,0,0,109,120,109,120,110,128,78,128,46,128,14,128,46,120,14,120,78,120,46,112,77,112,77,112,13,112,13,112,109,112,109,112,77,104,77,104,45,104,45,104,13,104,13,104,109,104,109,104,77,96,77,96,45,96,45,96,13,96,13,96,12,88,12,88,12,88,12,88,76,88, +76,88,76,88,76,88,44,88,44,88,44,88,44,88,12,80,12,80,12,80,12,80,108,96,108,96,108,96,108,96,76,80,76,80,76,80,76,80,44,80,44,80,44,80,44,80,12,72,12,72,12,72,12,72,107,88,107,88,107,88,107,88,107,88,107,88,107,88,107,88,75,72,75,72,75,72,75,72,75,72,75,72,75,72,75,72,43,72,43,72,43,72,43,72,43,72,43,72,43,72,43,72,11,64,11,64,11,64,11,64,11,64,11,64,11,64,11,64,107,80,107,80,107,80,107,80,107,80,107,80,107,80,107,80,75,64,75,64,75,64,75,64,75,64,75,64,75,64,75,64,43,64,43,64,43,64,43,64,43,64,43, +64,43,64,43,64,11,56,11,56,11,56,11,56,11,56,11,56,11,56,11,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,24,70,56,38,56,6,16,102,72,70,48,38,48,6,8,37,40,37,40,69,40,69,40,37,32,37,32,69,32,69,32,37,24,37,24,101,64,101,64,69,24,69,24,37,16,37,16,100,56,100,56,100,56,100,56,100,48,100,48,100,48,100,48,100,40,100,40,100,40,100,40,100,32,100,32,100,32,100,32,100,24,100,24,100,24,100,24,68,16,68,16,68,16,68,16,36,8,36,8,36,8,36,8,4,0,4,0,4,0,4,0,0,0,10,128,106,128,74,128,42,128,10,120,106,120,74,120,42,120,10, +112,106,112,74,112,42,112,10,104,41,104,41,104,9,96,9,96,73,104,73,104,41,96,41,96,9,88,9,88,105,104,105,104,73,96,73,96,41,88,41,88,9,80,9,80,104,96,104,96,104,96,104,96,72,88,72,88,72,88,72,88,40,80,40,80,40,80,40,80,8,72,8,72,8,72,8,72,104,88,104,88,104,88,104,88,72,80,72,80,72,80,72,80,40,72,40,72,40,72,40,72,8,64,8,64,8,64,8,64,7,56,7,56,7,56,7,56,7,56,7,56,7,56,7,56,7,48,7,48,7,48,7,48,7,48,7,48,7,48,7,48,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,7,40,7,40,7,40,7,40,7,40,7,40,7,40,7,40, +103,80,103,80,103,80,103,80,103,80,103,80,103,80,103,80,71,64,71,64,71,64,71,64,71,64,71,64,71,64,71,64,39,64,39,64,39,64,39,64,39,64,39,64,39,64,39,64,7,32,7,32,7,32,7,32,7,32,7,32,7,32,7,32,6,8,38,8,0,0,6,0,6,16,38,16,70,16,0,0,6,24,38,24,70,24,102,24,6,32,38,32,70,32,102,32,6,40,38,40,70,40,102,40,6,48,38,48,70,48,102,48,6,56,38,56,70,56,102,56,6,64,38,64,70,64,102,64,6,72,38,72,70,72,102,72,6,80,38,80,70,80,102,80,6,88,38,88,70,88,102,88,6,96,38,96,70,96,102,96,6,104,38,104,70,104,102,104,6,112, +38,112,70,112,102,112,6,120,38,120,70,120,102,120,6,128,38,128,70,128,102,128,0,0,67,16,2,0,2,0,33,8,33,8,33,8,33,8,103,32,103,32,72,32,40,32,71,24,71,24,39,24,39,24,6,32,6,32,6,32,6,32,6,24,6,24,6,24,6,24,6,16,6,16,6,16,6,16,102,24,102,24,102,24,102,24,38,16,38,16,38,16,38,16,6,8,6,8,6,8,6,8,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,3, +0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,3,0,0,0,19,0,0,0,1,0,0,0,18,0,0,0,0,0,0,0,17,0,0,0,4,0,0,0,16,0,0,0,3,0,0,0,23,0,0,0,1,0,0,0,22,0,0,0,0,0,0,0,21,0,0,0,4,0,0,0,20,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,4,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,12,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,4,0,0,0,13,0,0,0,255,0,0,0,8,0,0,0,1,0,0,0,19,0,0,0,2,0,0,0,18,0,0,0,4,0, +0,0,17,0,0,0,255,0,0,0,16,0,0,0,1,0,0,0,23,0,0,0,2,0,0,0,22,0,0,0,4,0,0,0,21,0,0,0,255,0,0,0,20,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,13,0,0,0,1,0,0,0,18,0,0,0,1,0,0,0,19,0,0,0,4,0,0,0,16,0,0,0,4,0,0,0,17,0,0,0,1,0,0,0,22,0,0,0,1,0,0,0,23,0,0,0,4,0,0,0,20,0,0,0,4,0,0,0,21,0,0,0,0, +0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,15,0,0,0,4,0,0,0,10,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,11,0,0,0,4,0,0,0,14,0,0,0,0,0,0,0,17,0,0,0,4,0,0,0,16,0,0,0,0,0,0,0,19,0,0,0,4,0,0,0,18,0,0,0,0,0,0,0,21,0,0,0,4,0,0,0,20,0,0,0,0,0,0,0,23,0,0,0,4,0,0,0,22,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,12,0,0,0,8,0,0,0,12,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0, +12,0,0,0,8,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,8,0,0,0,8,0,0,0,12,0,0,0,12,0,0,0,8,0,0,0,8,0,0,0,12,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108, +109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234, +235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,0,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,1,0,0,0,255,0, +0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,13,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0, +0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,4,0,0,0,2,0,0,0,10,0,0, +0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,2,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0, +0,0,4,0,0,0,9,0,0,0,255,0,0,0,12,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,4,0,0,0,13,0,0,0,255,0,0,0,8,0,0,0,1,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,4,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,255,0, +0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0, +0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,13,0,0,0,0,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0, +0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,13,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0, +0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,15,0,0,0,4,0,0,0,10,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,11,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,11,0,0,0,4,0,0,0,14,0,0, +0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0,0,0,14,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,5,6,7,8,9,10,12,13,15,17,20,22,25,28,32,36,40,45,50,56,63,71,80,90,101,113,127,144,162,182,203,226,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,3,4,4,4,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,1,1,2,1,1,2,1,2,3,1,2,3,2,2,3,2,2,4,2,3,4,2,3,4,3,3,5,3,4,6,3,4,6,4,5,7,4,5,8,4,6,9,5,7,10,6,8,11,6,8,13,7,10,14,8,11,16,9,12,18,10,13,20,11,15,23,13,17,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,69,67,79,68,69,82,32,73,78,73,84,73,65,76,73,90,65,84,73,79,78,32,70,65,73,76,69,68,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"i8",Ba,z.Pc);var $a=z.ub(M(12,"i8",L),8);w(0==$a%8); +var U={O:1,Q:2,Ef:3,De:4,ha:5,Zb:6,be:7,$e:8,V:9,oe:10,Ca:11,Of:11,Mc:12,qb:13,ye:14,mf:15,ga:16,Xb:17,Oc:18,Qa:19,Sa:20,pa:21,B:22,Ve:23,Lc:24,Nc:25,Lf:26,ze:27,hf:28,Ua:29,Bf:30,Oe:31,uf:32,ve:33,yf:34,df:42,Be:43,pe:44,Fe:45,Ge:46,He:47,Ne:48,Mf:49,Ye:50,Ee:51,te:35,af:37,ge:52,je:53,Pf:54,We:55,ke:56,le:57,ue:35,me:59,kf:60,Ze:61,If:62,jf:63,ef:64,ff:65,Af:66,bf:67,ee:68,Ff:69,qe:70,vf:71,Qe:72,we:73,ie:74,qf:76,he:77,zf:78,Ie:79,Je:80,Me:81,Le:82,Ke:83,lf:38,sb:39,Re:36,rb:40,Ta:95,tf:96,se:104, +Xe:105,fe:97,xf:91,of:88,gf:92,Cf:108,Wb:111,ce:98,re:103,Ue:101,Se:100,Jf:110,Ae:112,Yb:113,Jc:115,Hc:114,Ic:89,Pe:90,wf:93,Df:94,de:99,Te:102,Kc:106,Ra:107,Kf:109,Nf:87,xe:122,Gf:116,pf:95,cf:123,Ce:84,rf:75,ne:125,nf:131,sf:130,Hf:86},ab={"0":"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes", +12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func", +34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange", +53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)", +74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required", +90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected", +107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"},bb=0;function V(a){return K[bb>>2]=a} +function cb(a,b){for(var c=0,e=a.length-1;0<=e;e--){var f=a[e];"."===f?a.splice(e,1):".."===f?(a.splice(e,1),c++):c&&(a.splice(e,1),c--)}if(b)for(;c--;c)a.unshift("..");return a}function db(a){var b="/"===a.charAt(0),c="/"===a.substr(-1),a=cb(a.split("/").filter(function(a){return!!a}),!b).join("/");!a&&!b&&(a=".");a&&c&&(a+="/");return(b?"/":"")+a} +function eb(a){var b=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(a).slice(1),a=b[0],b=b[1];if(!a&&!b)return".";b&&(b=b.substr(0,b.length-1));return a+b}function W(a){if("/"===a)return"/";var b=a.lastIndexOf("/");return-1===b?a:a.substr(b+1)}function fb(){var a=Array.prototype.slice.call(arguments,0);return db(a.join("/"))}function X(a,b){return db(a+"/"+b)} +function gb(){for(var a="",b=m,c=arguments.length-1;-1<=c&&!b;c--){b=0<=c?arguments[c]:B.yb();"string"!==typeof b&&d(new TypeError("Arguments to path.resolve must be strings"));if(!b)return"";a=b+"/"+a;b="/"===b.charAt(0)}a=cb(a.split("/").filter(function(a){return!!a}),!b).join("/");return(b?"/":"")+a||"."} +function hb(a,b){function c(a){for(var b=0;bc?[]:a.slice(b,c-b+1)}for(var a=gb(a).substr(1),b=gb(b).substr(1),e=c(a.split("/")),f=c(b.split("/")),h=Math.min(e.length,f.length),j=h,l=0;la.k.length)&&(a.k=Y.ud(a),a.q=a.k.length);if(!a.k||a.k.subarray){var c=a.k?a.k.buffer.byteLength:0;c>=b||(b=Math.max(b,c*(1048576>c?2:1.125)|0),0!=c&&(b=Math.max(b,256)),c=a.k,a.k=new Uint8Array(b),0b)a.k.length=b;else for(;a.k.length=a.g.q)return 0;a=Math.min(a.g.q-f,e);w(0<=a);if(8b&&d(new B.e(U.B));return b},Ea:function(a,b,c){Y.lc(a.g,b+c);a.g.q=Math.max(a.g.q,b+c)},Ja:function(a,b,c,e,f,h,j){B.isFile(a.g.mode)||d(new B.e(U.Qa));c=a.g.k;if(!(j&2)&&(c.buffer===b||c.buffer=== +b.buffer))a=m,e=c.byteOffset;else{if(0>>0)%B.T.length},tc:function(a){var b=B.Fb(a.parent.id,a.name);a.ma=B.T[b];B.T[b]=a},uc:function(a){var b=B.Fb(a.parent.id,a.name);if(B.T[b]===a)B.T[b]=a.ma;else for(b=B.T[b];b;){if(b.ma===a){b.ma=a.ma;break}b=b.ma}},aa:function(a,b){var c=B.Gd(a);c&&d(new B.e(c,a));for(c=B.T[B.Fb(a.id,b)];c;c=c.ma){var e=c.name;if(c.parent.id===a.id&&e===b)return c}return B.ra(a,b)},createNode:function(a,b,c,e){B.Va||(B.Va=function(a,b,c,e){a|| +(a=this);this.parent=a;this.F=a.F;this.Ka=k;this.id=B.Jd++;this.name=b;this.mode=c;this.n={};this.p={};this.ob=e},B.Va.prototype={},Object.defineProperties(B.Va.prototype,{M:{get:function(){return 365===(this.mode&365)},set:function(a){a?this.mode|=365:this.mode&=-366}},write:{get:function(){return 146===(this.mode&146)},set:function(a){a?this.mode|=146:this.mode&=-147}},Dd:{get:function(){return B.J(this.mode)}},Gb:{get:function(){return B.ib(this.mode)}}}));a=new B.Va(a,b,c,e);B.tc(a);return a}, +zb:function(a){B.uc(a)},jb:function(a){return a===a.parent},ka:function(a){return!!a.Ka},isFile:function(a){return 32768===(a&61440)},J:function(a){return 16384===(a&61440)},Ia:function(a){return 40960===(a&61440)},ib:function(a){return 8192===(a&61440)},Bd:function(a){return 24576===(a&61440)},Cd:function(a){return 4096===(a&61440)},Ed:function(a){return 49152===(a&49152)},rd:{r:0,rs:1052672,"r+":2,w:577,wx:705,xw:705,"w+":578,"wx+":706,"xw+":706,a:1089,ax:1217,xa:1217,"a+":1090,"ax+":1218,"xa+":1218}, +wc:function(a){var b=B.rd[a];"undefined"===typeof b&&d(Error("Unknown file open mode: "+a));return b},sd:function(a){var b=["r","w","rw"][a&2097155];a&512&&(b+="w");return b},na:function(a,b){return B.vc?0:-1!==b.indexOf("r")&&!(a.mode&292)||-1!==b.indexOf("w")&&!(a.mode&146)||-1!==b.indexOf("x")&&!(a.mode&73)?U.qb:0},Gd:function(a){var b=B.na(a,"x");return b?b:!a.n.ra?U.qb:0},Jb:function(a,b){try{return B.aa(a,b),U.Xb}catch(c){}return B.na(a,"wx")},kb:function(a,b,c){var e;try{e=B.aa(a,b)}catch(f){return f.cb}if(a= +B.na(a,"wx"))return a;if(c){if(!B.J(e.mode))return U.Sa;if(B.jb(e)||B.da(e)===B.yb())return U.ga}else if(B.J(e.mode))return U.pa;return 0},Hd:function(a,b){return!a?U.Q:B.Ia(a.mode)?U.rb:B.J(a.mode)&&(0!==(b&2097155)||b&512)?U.pa:B.na(a,B.sd(b))},Qc:4096,Kd:function(a,b){for(var b=b||B.Qc,c=a||0;c<=b;c++)if(!B.oa[c])return c;d(new B.e(U.Lc))},qa:function(a){return B.oa[a]},fc:function(a,b,c){B.Wa||(B.Wa=n(),B.Wa.prototype={},Object.defineProperties(B.Wa.prototype,{object:{get:function(){return this.g}, +set:function(a){this.g=a}},yg:{get:function(){return 1!==(this.D&2097155)}},zg:{get:function(){return 0!==(this.D&2097155)}},xg:{get:function(){return this.D&1024}}}));var e=new B.Wa,f;for(f in a)e[f]=a[f];a=e;b=B.Kd(b,c);a.C=b;return B.oa[b]=a},dd:function(a){B.oa[a]=k},pc:function(a){return B.oa[a-1]},Eb:function(a){return a?a.C+1:0},bd:{open:function(a){a.p=B.td(a.g.ob).p;a.p.open&&a.p.open(a)},$:function(){d(new B.e(U.Ua))}},Ib:function(a){return a>>8},Gg:function(a){return a&255},la:function(a, +b){return a<<8|b},Ob:function(a,b){B.ic[a]={p:b}},td:function(a){return B.ic[a]},nc:function(a){for(var b=[],a=[a];a.length;){var c=a.pop();b.push(c);a.push.apply(a,c.La)}return b},Fc:function(a,b){function c(a){if(a){if(!c.pd)return c.pd=i,b(a)}else++f>=e.length&&b(k)}"function"===typeof a&&(b=a,a=m);var e=B.nc(B.root.F),f=0;e.forEach(function(b){if(!b.type.Fc)return c(k);b.type.Fc(b,a,c)})},F:function(a,b,c){var e="/"===c,f=!c,h;e&&B.root&&d(new B.e(U.ga));!e&&!f&&(h=B.u(c,{Bb:m}),c=h.path,h=h.g, +B.ka(h)&&d(new B.e(U.ga)),B.J(h.mode)||d(new B.e(U.Sa)));b={type:a,Kg:b,Id:c,La:[]};a=a.F(b);a.F=b;b.root=a;e?B.root=a:h&&(h.Ka=b,h.F&&h.F.La.push(b));return a},Qg:function(a){a=B.u(a,{Bb:m});B.ka(a.g)||d(new B.e(U.B));var a=a.g,b=a.Ka,c=B.nc(b);Object.keys(B.T).forEach(function(a){for(a=B.T[a];a;){var b=a.ma;-1!==c.indexOf(a.F)&&B.zb(a);a=b}});a.Ka=k;b=a.F.La.indexOf(b);w(-1!==b);a.F.La.splice(b,1)},ra:function(a,b){return a.n.ra(a,b)},ba:function(a,b,c){var e=B.u(a,{parent:i}).g,a=W(a);(!a||"."=== +a||".."===a)&&d(new B.e(U.B));var f=B.Jb(e,a);f&&d(new B.e(f));e.n.ba||d(new B.e(U.O));return e.n.ba(e,a,b,c)},create:function(a,b){b=(b!==g?b:438)&4095;b|=32768;return B.ba(a,b,0)},ea:function(a,b){b=(b!==g?b:511)&1023;b|=16384;return B.ba(a,b,0)},lb:function(a,b,c){"undefined"===typeof c&&(c=b,b=438);return B.ba(a,b|8192,c)},ca:function(a,b){gb(a)||d(new B.e(U.Q));var c=B.u(b,{parent:i}).g;c||d(new B.e(U.Q));var e=W(b),f=B.Jb(c,e);f&&d(new B.e(f));c.n.ca||d(new B.e(U.O));return c.n.ca(c,e,a)},rename:function(a, +b){var c=eb(a),e=eb(b),f=W(a),h=W(b),j,l,u;try{j=B.u(a,{parent:i}),l=j.g,j=B.u(b,{parent:i}),u=j.g}catch(q){d(new B.e(U.ga))}(!l||!u)&&d(new B.e(U.Q));l.F!==u.F&&d(new B.e(U.Oc));j=B.aa(l,f);e=hb(a,e);"."!==e.charAt(0)&&d(new B.e(U.B));e=hb(b,c);"."!==e.charAt(0)&&d(new B.e(U.sb));var x;try{x=B.aa(u,h)}catch(s){}if(j!==x){c=B.J(j.mode);(f=B.kb(l,f,c))&&d(new B.e(f));(f=x?B.kb(u,h,c):B.Jb(u,h))&&d(new B.e(f));l.n.rename||d(new B.e(U.O));(B.ka(j)||x&&B.ka(x))&&d(new B.e(U.ga));u!==l&&(f=B.na(l,"w"))&& +d(new B.e(f));try{B.H.willMovePath&&B.H.willMovePath(a,b)}catch(v){console.log("FS.trackingDelegate['willMovePath']('"+a+"', '"+b+"') threw an exception: "+v.message)}B.uc(j);try{l.n.rename(j,u,h)}catch(G){d(G)}finally{B.tc(j)}try{if(B.H.onMovePath)B.H.onMovePath(a,b)}catch(ua){console.log("FS.trackingDelegate['onMovePath']('"+a+"', '"+b+"') threw an exception: "+ua.message)}}},Oa:function(a){var b=B.u(a,{parent:i}).g,c=W(a),e=B.aa(b,c),f=B.kb(b,c,i);f&&d(new B.e(f));b.n.Oa||d(new B.e(U.O));B.ka(e)&& +d(new B.e(U.ga));try{B.H.willDeletePath&&B.H.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.n.Oa(b,c);B.zb(e);try{if(B.H.onDeletePath)B.H.onDeletePath(a)}catch(j){console.log("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+j.message)}},Na:function(a){a=B.u(a,{R:i}).g;a.n.Na||d(new B.e(U.Sa));return a.n.Na(a)},za:function(a){var b=B.u(a,{parent:i}).g,c=W(a),e=B.aa(b,c),f=B.kb(b,c,m);f&&(f===U.pa&&(f=U.O), +d(new B.e(f)));b.n.za||d(new B.e(U.O));B.ka(e)&&d(new B.e(U.ga));try{B.H.willDeletePath&&B.H.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.n.za(b,c);B.zb(e);try{if(B.H.onDeletePath)B.H.onDeletePath(a)}catch(j){console.log("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+j.message)}},ta:function(a){(a=B.u(a).g)||d(new B.e(U.Q));a.n.ta||d(new B.e(U.B));return a.n.ta(a)},Dc:function(a,b){var c=B.u(a,{R:!b}).g; +c||d(new B.e(U.Q));c.n.S||d(new B.e(U.O));return c.n.S(c)},Eg:function(a){return B.Dc(a,i)},Ya:function(a,b,c){a="string"===typeof a?B.u(a,{R:!c}).g:a;a.n.I||d(new B.e(U.O));a.n.I(a,{mode:b&4095|a.mode&-4096,timestamp:Date.now()})},Bg:function(a,b){B.Ya(a,b,i)},jg:function(a,b){var c=B.qa(a);c||d(new B.e(U.V));B.Ya(c.g,b)},dc:function(a,b,c,e){a="string"===typeof a?B.u(a,{R:!e}).g:a;a.n.I||d(new B.e(U.O));a.n.I(a,{timestamp:Date.now()})},Cg:function(a,b,c){B.dc(a,b,c,i)},kg:function(a,b,c){(a=B.qa(a))|| +d(new B.e(U.V));B.dc(a.g,b,c)},truncate:function(a,b){0>b&&d(new B.e(U.B));var c;c="string"===typeof a?B.u(a,{R:i}).g:a;c.n.I||d(new B.e(U.O));B.J(c.mode)&&d(new B.e(U.pa));B.isFile(c.mode)||d(new B.e(U.B));var e=B.na(c,"w");e&&d(new B.e(e));c.n.I(c,{size:b,timestamp:Date.now()})},mg:function(a,b){var c=B.qa(a);c||d(new B.e(U.V));0===(c.D&2097155)&&d(new B.e(U.B));B.truncate(c.g,b)},Rg:function(a,b,c){a=B.u(a,{R:i}).g;a.n.I(a,{timestamp:Math.max(b,c)})},open:function(a,b,c,e,f){""===a&&d(new B.e(U.Q)); +var b="string"===typeof b?B.wc(b):b,c=b&64?("undefined"===typeof c?438:c)&4095|32768:0,h;if("object"===typeof a)h=a;else{a=db(a);try{h=B.u(a,{R:!(b&131072)}).g}catch(j){}}var l=m;b&64&&(h?b&128&&d(new B.e(U.Xb)):(h=B.ba(a,c,0),l=i));h||d(new B.e(U.Q));B.ib(h.mode)&&(b&=-513);l||(c=B.Hd(h,b))&&d(new B.e(c));b&512&&B.truncate(h,0);b&=-641;e=B.fc({g:h,path:B.da(h),D:b,seekable:i,position:0,p:h.p,$d:[],error:m},e,f);e.p.open&&e.p.open(e);p.logReadFiles&&!(b&1)&&(B.Mb||(B.Mb={}),a in B.Mb||(B.Mb[a]=1, +p.printErr("read file: "+a)));try{B.H.onOpenFile&&(f=0,1!==(b&2097155)&&(f|=B.Gc.yc.Rc),0!==(b&2097155)&&(f|=B.Gc.yc.Sc),B.H.onOpenFile(a,f))}catch(u){console.log("FS.trackingDelegate['onOpenFile']('"+a+"', flags) threw an exception: "+u.message)}return e},close:function(a){try{a.p.close&&a.p.close(a)}catch(b){d(b)}finally{B.dd(a.C)}},$:function(a,b,c){(!a.seekable||!a.p.$)&&d(new B.e(U.Ua));a.position=a.p.$(a,b,c);a.$d=[];return a.position},M:function(a,b,c,e,f){(0>e||0>f)&&d(new B.e(U.B));1===(a.D& +2097155)&&d(new B.e(U.V));B.J(a.g.mode)&&d(new B.e(U.pa));a.p.M||d(new B.e(U.B));var h=i;"undefined"===typeof f?(f=a.position,h=m):a.seekable||d(new B.e(U.Ua));b=a.p.M(a,b,c,e,f);h||(a.position+=b);return b},write:function(a,b,c,e,f,h){(0>e||0>f)&&d(new B.e(U.B));0===(a.D&2097155)&&d(new B.e(U.V));B.J(a.g.mode)&&d(new B.e(U.pa));a.p.write||d(new B.e(U.B));a.D&1024&&B.$(a,0,2);var j=i;"undefined"===typeof f?(f=a.position,j=m):a.seekable||d(new B.e(U.Ua));b=a.p.write(a,b,c,e,f,h);j||(a.position+=b); +try{if(a.path&&B.H.onWriteToFile)B.H.onWriteToFile(a.path)}catch(l){console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: "+l.message)}return b},Ea:function(a,b,c){(0>b||0>=c)&&d(new B.e(U.B));0===(a.D&2097155)&&d(new B.e(U.V));!B.isFile(a.g.mode)&&!B.J(node.mode)&&d(new B.e(U.Qa));a.p.Ea||d(new B.e(U.Ta));a.p.Ea(a,b,c)},Ja:function(a,b,c,e,f,h,j){1===(a.D&2097155)&&d(new B.e(U.qb));a.p.Ja||d(new B.e(U.Qa));return a.p.Ja(a,b,c,e,f,h,j)},Ha:function(a,b,c){a.p.Ha||d(new B.e(U.Nc)); +return a.p.Ha(a,b,c)},Mg:function(a,b){b=b||{};b.D=b.D||"r";b.encoding=b.encoding||"binary";"utf8"!==b.encoding&&"binary"!==b.encoding&&d(Error('Invalid encoding type "'+b.encoding+'"'));var c,e=B.open(a,b.D),f=B.Dc(a).size,h=new Uint8Array(f);B.M(e,h,0,f,0);if("utf8"===b.encoding){c="";for(var j=new z.Da,l=0;l>2]=B.Eb(a);w(0===a.C,"invalid handle for stdin ("+a.C+")");a=B.open("/dev/stdout","w");K[pb>>2]=B.Eb(a);w(1===a.C,"invalid handle for stdout ("+a.C+")");a=B.open("/dev/stderr","w");K[qb>>2]=B.Eb(a);w(2===a.C,"invalid handle for stderr ("+a.C+")")},jc:function(){B.e||(B.e=function(a,b){this.g=b;this.Xd=function(a){this.cb=a;for(var b in U)if(U[b]=== +a){this.code=b;break}};this.Xd(a);this.message=ab[a]},B.e.prototype=Error(),[U.Q].forEach(function(a){B.Db[a]=new B.e(a);B.Db[a].stack=""}))},Zd:function(){B.jc();B.T=Array(4096);B.F(Y,{},"/");B.fd();B.ed()},Ga:function(a,b,c){w(!B.Ga.hb,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");B.Ga.hb=i;B.jc();p.stdin=a||p.stdin;p.stdout=b||p.stdout;p.stderr= +c||p.stderr;B.od()},Qd:function(){B.Ga.hb=m;for(var a=0;athis.length-1||0>a)){var b=a%this.cd;return this.yd(a/ +this.cd|0)[b]}};h.prototype.Wd=function(a){this.yd=a};h.prototype.bc=function(){var a=new XMLHttpRequest;a.open("HEAD",c,m);a.send(k);200<=a.status&&300>a.status||304===a.status||d(Error("Couldn't load "+c+". Status: "+a.status));var b=Number(a.getResponseHeader("Content-length")),e,f=1048576;if(!((e=a.getResponseHeader("Accept-Ranges"))&&"bytes"===e))f=b;var h=this;h.Wd(function(a){var e=a*f,j=(a+1)*f-1,j=Math.min(j,b-1);if("undefined"===typeof h.Za[a]){var l=h.Za;e>j&&d(Error("invalid range ("+ +e+", "+j+") or no bytes requested!"));j>b-1&&d(Error("only "+b+" bytes available! programmer error!"));var q=new XMLHttpRequest;q.open("GET",c,m);b!==f&&q.setRequestHeader("Range","bytes="+e+"-"+j);"undefined"!=typeof Uint8Array&&(q.responseType="arraybuffer");q.overrideMimeType&&q.overrideMimeType("text/plain; charset=x-user-defined");q.send(k);200<=q.status&&300>q.status||304===q.status||d(Error("Couldn't load "+c+". Status: "+q.status));e=q.response!==g?new Uint8Array(q.response||[]):Va(q.responseText|| +"",i);l[a]=e}"undefined"===typeof h.Za[a]&&d(Error("doXHR failed!"));return h.Za[a]});this.Uc=b;this.Tc=f;this.Hb=i};if("undefined"!==typeof XMLHttpRequest){ca||d("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc");var j=new h;Object.defineProperty(j,"length",{get:function(){this.Hb||this.bc();return this.Uc}});Object.defineProperty(j,"chunkSize",{get:function(){this.Hb||this.bc();return this.Tc}});j={Gb:m,k:j}}else j={Gb:m,url:c}; +var l=B.gd(a,b,j,e,f);j.k?l.k=j.k:j.url&&(l.k=k,l.url=j.url);Object.defineProperty(l,"usedBytes",{get:function(){return this.k.length}});var u={};Object.keys(l.p).forEach(function(a){var b=l.p[a];u[a]=function(){B.mc(l)||d(new B.e(U.ha));return b.apply(k,arguments)}});u.M=function(a,b,c,e,f){B.mc(l)||d(new B.e(U.ha));a=a.g.k;if(f>=a.length)return 0;e=Math.min(a.length-f,e);w(0<=e);if(a.slice)for(var h=0;h>h-6&63,h=h-6,c=c+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[q]}2==h?(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&3)<<4],c+="=="):4==h&&(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&15)<<2],c+="="); +s.src="data:audio/x-"+b.substr(-3)+";base64,"+c;f(s)}};s.src=l;p.noExitRuntime=i;setTimeout(function(){H||f(s)},1E4)}else return h()}});var v=p.canvas;v&&(v.Pb=v.requestPointerLock||v.mozRequestPointerLock||v.webkitRequestPointerLock||v.msRequestPointerLock||n(),v.kc=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock||document.msExitPointerLock||n(),v.kc=v.kc.bind(document),document.addEventListener("pointerlockchange",q,m),document.addEventListener("mozpointerlockchange", +q,m),document.addEventListener("webkitpointerlockchange",q,m),document.addEventListener("mspointerlockchange",q,m),p.elementPointerLock&&v.addEventListener("click",function(a){!rb&&v.Pb&&(v.Pb(),a.preventDefault())},m))}var G=b?gb(X(a,b)):a;Ya();"string"==typeof c?yb(c,function(a){x(a)},j):x(c)},indexedDB:function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},Ub:function(){return"EM_FS_"+window.location.pathname},Vb:20,Ba:"FILE_DATA",Og:function(a,b,c){var b= +b||n(),c=c||n(),e=B.indexedDB();try{var f=e.open(B.Ub(),B.Vb)}catch(h){return c(h)}f.Ld=function(){console.log("creating db");f.result.createObjectStore(B.Ba)};f.onsuccess=function(){var e=f.result.transaction([B.Ba],"readwrite"),h=e.objectStore(B.Ba),u=0,q=0,x=a.length;a.forEach(function(a){a=h.put(B.vb(a).object.k,a);a.onsuccess=function(){u++;u+q==x&&(0==q?b():c())};a.onerror=function(){q++;u+q==x&&(0==q?b():c())}});e.onerror=c};f.onerror=c},Dg:function(a,b,c){var b=b||n(),c=c||n(),e=B.indexedDB(); +try{var f=e.open(B.Ub(),B.Vb)}catch(h){return c(h)}f.Ld=c;f.onsuccess=function(){var e=f.result;try{var h=e.transaction([B.Ba],"readonly")}catch(u){c(u);return}var q=h.objectStore(B.Ba),x=0,s=0,v=a.length;a.forEach(function(a){var e=q.get(a);e.onsuccess=function(){B.vb(a).Ab&&B.za(a);B.xb(eb(a),W(a),e.result,i,i,i);x++;x+s==v&&(0==s?b():c())};e.onerror=function(){s++;x+s==v&&(0==s?b():c())}});h.onerror=c};f.onerror=c}};function zb(){d("TODO")} +var Z={F:function(){p.websocket=p.websocket&&"object"===typeof p.websocket?p.websocket:{};p.websocket.tb={};p.websocket.on=function(a,b){"function"===typeof b&&(this.tb[a]=b);return this};p.websocket.P=function(a,b){"function"===typeof this.tb[a]&&this.tb[a].call(this,b)};return B.createNode(k,"/",16895,0)},nd:function(a,b,c){c&&w(1==b==(6==c));a={qd:a,type:b,protocol:c,G:k,error:k,Ma:{},Kb:[],ua:[],wa:Z.L};b=Z.mb();c=B.createNode(Z.root,b,49152,0);c.va=a;b=B.fc({path:b,g:c,D:B.wc("r+"),seekable:m, +p:Z.p});a.A=b;return a},wd:function(a){a=B.qa(a);return!a||!B.Ed(a.g.mode)?k:a.g.va},p:{zc:function(a){a=a.g.va;return a.wa.zc(a)},Ha:function(a,b,c){a=a.g.va;return a.wa.Ha(a,b,c)},M:function(a,b,c,e){a=a.g.va;e=a.wa.Rd(a,e);if(!e)return 0;b.set(e.buffer,c);return e.buffer.length},write:function(a,b,c,e){a=a.g.va;return a.wa.Vd(a,b,c,e)},close:function(a){a=a.g.va;a.wa.close(a)}},mb:function(){Z.mb.gc||(Z.mb.gc=0);return"socket["+Z.mb.gc++ +"]"},L:{$a:function(a,b,c){var e;"object"===typeof b&&(e= +b,c=b=k);if(e)e._socket?(b=e._socket.remoteAddress,c=e._socket.remotePort):((c=/ws[s]?:\/\/([^:]+):(\d+)/.exec(e.url))||d(Error("WebSocket URL must be in the format ws(s)://address:port")),b=c[1],c=parseInt(c[2],10));else try{var f=p.websocket&&"object"===typeof p.websocket,h="ws:#".replace("#","//");f&&"string"===typeof p.websocket.url&&(h=p.websocket.url);if("ws://"===h||"wss://"===h)var j=b.split("/"),h=h+j[0]+":"+c+"/"+j.slice(1).join("/");j="binary";f&&"string"===typeof p.websocket.subprotocol&& +(j=p.websocket.subprotocol);var j=j.replace(/^ +| +$/g,"").split(/ *, */),l=t?{protocol:j.toString()}:j;e=new (t?(null)("ws"):window.WebSocket)(h,l);e.binaryType="arraybuffer"}catch(u){d(new B.e(U.Yb))}b={W:b,port:c,o:e,ab:[]};Z.L.$b(a,b);Z.L.zd(a,b);2===a.type&&"undefined"!==typeof a.ya&&b.ab.push(new Uint8Array([255,255,255,255,112,111,114,116,(a.ya&65280)>>8,a.ya&255]));return b},gb:function(a,b,c){return a.Ma[b+":"+c]},$b:function(a,b){a.Ma[b.W+":"+b.port]=b},Bc:function(a,b){delete a.Ma[b.W+ +":"+b.port]},zd:function(a,b){function c(){p.websocket.P("open",a.A.C);try{for(var c=b.ab.shift();c;)b.o.send(c),c=b.ab.shift()}catch(e){b.o.close()}}function e(c){w("string"!==typeof c&&c.byteLength!==g);var c=new Uint8Array(c),e=f;f=m;e&&10===c.length&&255===c[0]&&255===c[1]&&255===c[2]&&255===c[3]&&112===c[4]&&111===c[5]&&114===c[6]&&116===c[7]?(c=c[8]<<8|c[9],Z.L.Bc(a,b),b.port=c,Z.L.$b(a,b)):(a.ua.push({W:b.W,port:b.port,data:c}),p.websocket.P("message",a.A.C))}var f=i;t?(b.o.on("open",c),b.o.on("message", +function(a,b){b.binary&&e((new Uint8Array(a)).buffer)}),b.o.on("close",function(){p.websocket.P("close",a.A.C)}),b.o.on("error",function(){a.error=U.Wb;p.websocket.P("error",[a.A.C,a.error,"ECONNREFUSED: Connection refused"])})):(b.o.onopen=c,b.o.onclose=function(){p.websocket.P("close",a.A.C)},b.o.onmessage=function(a){e(a.data)},b.o.onerror=function(){a.error=U.Wb;p.websocket.P("error",[a.A.C,a.error,"ECONNREFUSED: Connection refused"])})},zc:function(a){if(1===a.type&&a.G)return a.Kb.length?65: +0;var b=0,c=1===a.type?Z.L.gb(a,a.Y,a.Z):k;if(a.ua.length||!c||c&&c.o.readyState===c.o.Pa||c&&c.o.readyState===c.o.CLOSED)b|=65;if(!c||c&&c.o.readyState===c.o.OPEN)b|=4;if(c&&c.o.readyState===c.o.Pa||c&&c.o.readyState===c.o.CLOSED)b|=16;return b},Ha:function(a,b,c){switch(b){case 21531:return b=0,a.ua.length&&(b=a.ua[0].data.length),K[c>>2]=b,0;default:return U.B}},close:function(a){if(a.G){try{a.G.close()}catch(b){}a.G=k}for(var c=Object.keys(a.Ma),e=0;e>0]=c;if(-1==Ab(Cb(b),Eb.Cc,1)){if(c=B.pc(b))c.error=i;return-1}return c}function Fb(a){Fb.$c||(E=E+4095&-4096,Fb.$c=i,w(z.bb),Fb.Wc=z.bb,z.bb=function(){A("cannot dynamically allocate, sbrk now has control")});var b=E;0!=a&&Fb.Wc(a);return b}p._memset=Gb;function Hb(a,b,c){window._broadwayOnPictureDecoded(a,b,c)}p._broadwayOnPictureDecoded=Hb;function Ib(){window._broadwayOnHeadersDecoded()}p._broadwayOnHeadersDecoded=Ib; +function Jb(a,b){Kb=a;Lb=b;if(!Mb)return 1;0==a?(Nb=function(){setTimeout(Ob,b)},Pb="timeout"):1==a&&(Nb=function(){Qb(Ob)},Pb="rAF");return 0} +function Rb(a,b,c,e){p.noExitRuntime=i;w(!Mb,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");Mb=a;Sb=e;var f=Tb;Ob=function(){if(!H)if(0=bc;)bc+=1E3/60;b=Math.max(bc-b,0);setTimeout(a,b)}function Qb(a){"undefined"===typeof window?cc(a):(window.requestAnimationFrame||(window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||cc),window.requestAnimationFrame(a))} +function xb(a){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",bmp:"image/bmp",ogg:"audio/ogg",wav:"audio/wav",mp3:"audio/mpeg"}[a.substr(a.lastIndexOf(".")+1)]} +function yb(a,b,c){function e(){c?c():d('Loading data file "'+a+'" failed.')}var f=new XMLHttpRequest;f.open("GET",a,i);f.responseType="arraybuffer";f.onload=function(){if(200==f.status||0==f.status&&f.response){var c=f.response;w(c,'Loading data file "'+a+'" failed (no arrayBuffer).');b(new Uint8Array(c));Za()}else e()};f.onerror=e;f.send(k);Ya()}var dc=[];function ec(){var a=p.canvas;dc.forEach(function(b){b(a.width,a.height)})} +function fc(a,b,c){b&&c?(a.ae=b,a.Ad=c):(b=a.ae,c=a.Ad);var e=b,f=c;p.forcedAspectRatio&&0>2]=0;R.unshift({ja:n()});Qa.push({ja:n()});var lb=new z.Da;t&&((null)("fs"),process.platform.match(/^win/));R.push({ja:function(){Z.root=B.F(Z,{},k)}}); +Eb.Cc=M([0],"i8",L); +p.requestFullScreen=function(a,b){function c(){Yb=m;var a=e.parentNode;(document.webkitFullScreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.mozFullscreenElement||document.fullScreenElement||document.fullscreenElement||document.msFullScreenElement||document.msFullscreenElement||document.webkitCurrentFullScreenElement)===a?(e.cc=document.cancelFullScreen||document.mozCancelFullScreen||document.webkitCancelFullScreen||document.msExitFullscreen||document.exitFullscreen|| +n(),e.cc=e.cc.bind(document),$b&&e.Pb(),Yb=i,ac&&("undefined"!=typeof SDL&&(a=Ha[SDL.screen+0*z.ia>>2],K[SDL.screen+0*z.ia>>2]=a|8388608),ec())):(a.parentNode.insertBefore(e,a),a.parentNode.removeChild(a),ac&&("undefined"!=typeof SDL&&(a=Ha[SDL.screen+0*z.ia>>2],K[SDL.screen+0*z.ia>>2]=a&-8388609),ec()));if(p.onFullScreen)p.onFullScreen(Yb);fc(e)}$b=a;ac=b;"undefined"===typeof $b&&($b=i);"undefined"===typeof ac&&(ac=m);var e=p.canvas;Zb||(Zb=i,document.addEventListener("fullscreenchange",c,m),document.addEventListener("mozfullscreenchange", +c,m),document.addEventListener("webkitfullscreenchange",c,m),document.addEventListener("MSFullscreenChange",c,m));var f=document.createElement("div");e.parentNode.insertBefore(f,e);f.appendChild(e);f.Td=f.requestFullScreen||f.mozRequestFullScreen||f.msRequestFullscreen||(f.webkitRequestFullScreen?function(){f.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}:k);f.Td()};p.requestAnimationFrame=function(a){Qb(a)};p.setCanvasSize=function(a,b,c){fc(p.canvas,a,b);c||ec()}; +p.pauseMainLoop=function(){Nb=k;Tb++};p.resumeMainLoop=function(){Tb++;var a=Kb,b=Lb,c=Mb;Mb=k;Rb(c,0,m,Sb);Jb(a,b)};p.getUserMedia=function(){window.qc||(window.qc=navigator.getUserMedia||navigator.mozGetUserMedia);window.qc(g)};Ja=y=z.ub(D);Ka=Ja+Ma;La=E=z.ub(Ka);w(La>2],a=Db(a,b);return 0>a?a:0>Eb(10,b)?-1:a+1},_fflush:n(),_fputc:Eb,_send:function(a,b,c){return!Z.wd(a)?(V(U.V),-1):Ab(a,b,c)},_pwrite:function(a,b,c,e){a=B.qa(a);if(!a)return V(U.V),-1;try{return B.write(a,I,b,c,e)}catch(f){return B.sc(f),-1}},_fputs:Db,_emscripten_set_main_loop:Rb, +_abort:function(){p.abort()},___setErrNo:V,_sbrk:Fb,_mkport:zb,_emscripten_set_main_loop_timing:Jb,_emscripten_memcpy_big:function(a,b,c){N.set(N.subarray(b,b+c),a);return a},_fileno:Cb,_broadwayOnHeadersDecoded:Ib,_write:Ab,_time:function(a){var b=Date.now()/1E3|0;a&&(K[a>>2]=b);return b},_sysconf:function(a){switch(a){case 30:return 4096;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 79:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809; +case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32; +case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1E3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:return"object"===typeof navigator?navigator.hardwareConcurrency||1:1}V(U.B);return-1}, +___errno_location:function(){return bb},STACKTOP:y,STACK_MAX:Ka,tempDoublePtr:$a,ABORT:H,NaN:NaN,Infinity:Infinity};// EMSCRIPTEN_START_ASM +var $=(function(global,env,buffer) { +"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=0;var n=0;var o=0;var p=0;var q=+env.NaN,r=+env.Infinity;var s=0,t=0,u=0,v=0,w=0.0,x=0,y=0,z=0,A=0.0;var B=0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=global.Math.floor;var M=global.Math.abs;var N=global.Math.sqrt;var O=global.Math.pow;var P=global.Math.cos;var Q=global.Math.sin;var R=global.Math.tan;var S=global.Math.acos;var T=global.Math.asin;var U=global.Math.atan;var V=global.Math.atan2;var W=global.Math.exp;var X=global.Math.log;var Y=global.Math.ceil;var Z=global.Math.imul;var _=env.abort;var $=env.assert;var aa=env.min;var ba=env.invoke_viiiii;var ca=env._broadwayOnPictureDecoded;var da=env._puts;var ea=env._fflush;var fa=env._fputc;var ga=env._send;var ha=env._pwrite;var ia=env._fputs;var ja=env._emscripten_set_main_loop;var ka=env._abort;var la=env.___setErrNo;var ma=env._sbrk;var na=env._mkport;var oa=env._emscripten_set_main_loop_timing;var pa=env._emscripten_memcpy_big;var qa=env._fileno;var ra=env._broadwayOnHeadersDecoded;var sa=env._write;var ta=env._time;var ua=env._sysconf;var va=env.___errno_location;var wa=0.0; +// EMSCRIPTEN_START_FUNCS +function Sb(a,f,g,h,j,k){a=a|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0;X=i;i=i+32|0;W=X;p=c[j+4>>2]|0;V=(h>>>0)/(p>>>0)|0;U=V<<4;V=h-(Z(V,p)|0)<<4;c[W+4>>2]=p;c[W+8>>2]=c[j+8>>2];p=c[a>>2]|0;do if((p|0)==1|(p|0)==0){A=c[f+144>>2]|0;l=a+4|0;n=c[a+200>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){o=n+152|0;o=e[o>>1]|e[o+2>>1]<<16;m=1;v=o&65535;o=o>>>16&65535;s=c[n+104>>2]|0}else{m=1;v=0;o=0;s=-1}else{m=0;v=0;o=0;s=-1}n=c[a+204>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){w=n+172|0;w=e[w>>1]|e[w+2>>1]<<16;u=w&65535;q=1;r=c[n+108>>2]|0;w=w>>>16&65535}else{u=0;q=1;r=-1;w=0}else{u=0;q=0;r=-1;w=0}do if(!p)if(!((m|0)==0|(q|0)==0)){if((s|0)==0?((o&65535)<<16|v&65535|0)==0:0){n=0;o=0;break}if((r|0)==0?((w&65535)<<16|u&65535|0)==0:0){n=0;o=0}else T=16}else{n=0;o=0}else T=16;while(0);if((T|0)==16){y=b[f+160>>1]|0;z=b[f+162>>1]|0;n=c[a+208>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){t=n+172|0;p=c[n+108>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;T=25}else{p=-1;t=0;T=25}else T=20;do if((T|0)==20){p=c[a+212>>2]|0;if((p|0)!=0?(c[p+4>>2]|0)==(c[l>>2]|0):0){if((c[p>>2]|0)>>>0>=6){p=-1;t=0;T=25;break}t=p+192|0;p=c[p+112>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;T=25;break}if((m|0)==0|(q|0)!=0){p=-1;t=0;T=25}else n=v}while(0);do if((T|0)==25){m=(s|0)==(A|0);n=(r|0)==(A|0);if(((n&1)+(m&1)+((p|0)==(A|0)&1)|0)==1){if(m|n){n=m?v:u;o=m?o:w;break}n=t&65535;o=t>>>16&65535;break}n=v<<16>>16;l=u<<16>>16;p=t<<16>>16;if(u<<16>>16>v<<16>>16)m=l;else{m=n;n=(l|0)<(n|0)?l:n}if((m|0)<(p|0))p=m;else p=(n|0)>(p|0)?n:p;n=o<<16>>16;m=w<<16>>16;l=t>>16;if(w<<16>>16>o<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=p&65535;o=o&65535}while(0);n=(n&65535)+(y&65535)|0;o=(o&65535)+(z&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}else{n=n&65535;o=o&65535}}l=ic(g,A)|0;if(!l){G=1;i=X;return G|0}else{G=a+132|0;E=a+136|0;D=a+140|0;C=a+144|0;B=a+148|0;z=a+152|0;y=a+156|0;x=a+160|0;w=a+164|0;v=a+168|0;m=a+172|0;p=a+176|0;q=a+180|0;r=a+184|0;s=a+188|0;F=a+192|0;b[a+192>>1]=n;b[a+194>>1]=o;F=e[F>>1]|e[F+2>>1]<<16;b[s>>1]=F;b[s+2>>1]=F>>>16;b[r>>1]=F;b[r+2>>1]=F>>>16;b[q>>1]=F;b[q+2>>1]=F>>>16;b[p>>1]=F;b[p+2>>1]=F>>>16;b[m>>1]=F;b[m+2>>1]=F>>>16;b[v>>1]=F;b[v+2>>1]=F>>>16;b[w>>1]=F;b[w+2>>1]=F>>>16;b[x>>1]=F;b[x+2>>1]=F>>>16;b[y>>1]=F;b[y+2>>1]=F>>>16;b[z>>1]=F;b[z+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+100>>2]=A;c[a+104>>2]=A;c[a+108>>2]=A;c[a+112>>2]=A;c[a+116>>2]=l;c[a+120>>2]=l;c[a+124>>2]=l;c[a+128>>2]=l;c[W>>2]=l;dc(k,a+132|0,W,V,U,0,0,16,16);break}}else if((p|0)==3){x=b[f+160>>1]|0;y=b[f+162>>1]|0;C=c[f+144>>2]|0;u=a+4|0;o=c[a+200>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){w=o+152|0;w=e[w>>1]|e[w+2>>1]<<16;n=1;s=w&65535;w=w>>>16&65535;o=c[o+104>>2]|0}else{n=1;s=0;w=0;o=-1}else{n=0;s=0;w=0;o=-1}a:do if((o|0)==(C|0)){n=s;o=w}else{o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){G=o+172|0;G=e[G>>1]|e[G+2>>1]<<16;t=o+188|0;p=c[o+108>>2]|0;l=c[o+112>>2]|0;n=G&65535;o=G>>>16&65535;t=e[t>>1]|e[t+2>>1]<<16}else{p=-1;l=-1;n=0;o=0;t=0}else T=107;do if((T|0)==107){o=c[a+212>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0){if((c[o>>2]|0)>>>0>=6){p=-1;l=-1;n=0;o=0;t=0;break}t=o+192|0;p=-1;l=c[o+112>>2]|0;n=0;o=0;t=e[t>>1]|e[t+2>>1]<<16;break}if(!n){p=-1;l=-1;n=0;o=0;t=0}else{n=s;o=w;break a}}while(0);m=(p|0)==(C|0);if(((m&1)+((l|0)==(C|0)&1)|0)==1){if(m)break;n=t&65535;o=t>>>16&65535;break}l=s<<16>>16;p=n<<16>>16;q=t<<16>>16;if(n<<16>>16>s<<16>>16){m=p;n=l}else{m=l;n=(p|0)<(l|0)?p:l}if((m|0)<(q|0))q=m;else q=(n|0)>(q|0)?n:q;n=w<<16>>16;m=o<<16>>16;l=t>>16;if(o<<16>>16>w<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=q&65535;o=o&65535}while(0);n=(n&65535)+(x&65535)|0;o=(o&65535)+(y&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}m=ic(g,C)|0;if(!m){G=1;i=X;return G|0}x=a+132|0;z=a+136|0;A=a+140|0;y=a+144|0;G=a+164|0;F=a+168|0;E=a+172|0;w=a+176|0;b[a+176>>1]=n;b[a+178>>1]=o;w=e[w>>1]|e[w+2>>1]<<16;b[E>>1]=w;b[E+2>>1]=w>>>16;b[F>>1]=w;b[F+2>>1]=w>>>16;b[G>>1]=w;b[G+2>>1]=w>>>16;b[y>>1]=w;b[y+2>>1]=w>>>16;b[A>>1]=w;b[A+2>>1]=w>>>16;b[z>>1]=w;b[z+2>>1]=w>>>16;b[x>>1]=w;b[x+2>>1]=w>>>16;c[a+100>>2]=C;c[a+108>>2]=C;x=a+116|0;c[x>>2]=m;c[a+124>>2]=m;z=b[f+164>>1]|0;A=b[f+166>>1]|0;y=c[f+148>>2]|0;o=c[a+208>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){r=o+172|0;o=c[o+108>>2]|0;p=1;r=e[r>>1]|e[r+2>>1]<<16}else{o=-1;p=1;r=0}else{o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){r=o+176|0;o=c[o+108>>2]|0;p=1;r=e[r>>1]|e[r+2>>1]<<16}else{o=-1;p=1;r=0}else{o=-1;p=0;r=0}}do if((o|0)!=(y|0)){s=w&65535;o=w>>>16;v=o&65535;n=c[a+204>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[u>>2]|0):0)if((c[n>>2]|0)>>>0<6){u=n+188|0;u=e[u>>1]|e[u+2>>1]<<16;p=c[n+112>>2]|0;l=u&65535;u=u>>>16&65535}else{p=-1;l=0;u=0}else if(!p){m=w;break}else{p=-1;l=0;u=0}m=(C|0)==(y|0);n=(p|0)==(y|0);if(((n&1)+(m&1)|0)==1){if(m){m=w;break}if(n){o=u&65535;m=o<<16|l&65535;break}else{m=r;o=r>>>16;break}}o=w<<16>>16;p=l<<16>>16;q=r<<16>>16;if(l<<16>>16>s<<16>>16)m=p;else{m=o;o=(p|0)<(o|0)?p:o}if((m|0)>=(q|0))m=(o|0)>(q|0)?o:q;n=w>>16;l=u<<16>>16;p=r>>16;if(u<<16>>16>v<<16>>16)o=l;else{o=n;n=(l|0)<(n|0)?l:n}if((o|0)>=(p|0))o=(n|0)>(p|0)?n:p}else{m=r;o=r>>>16}while(0);m=(m&65535)+(z&65535)|0;n=(o&65535)+(A&65535)|0;if(((m<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((n<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}o=ic(g,y)|0;if(!o){G=1;i=X;return G|0}else{G=a+148|0;E=a+152|0;D=a+156|0;C=a+160|0;B=a+180|0;A=a+184|0;z=a+188|0;F=a+192|0;b[a+192>>1]=m;b[a+194>>1]=n;F=e[F>>1]|e[F+2>>1]<<16;b[z>>1]=F;b[z+2>>1]=F>>>16;b[A>>1]=F;b[A+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+104>>2]=y;c[a+112>>2]=y;F=a+120|0;c[F>>2]=o;c[a+128>>2]=o;c[W>>2]=c[x>>2];dc(k,a+132|0,W,V,U,0,0,8,16);c[W>>2]=c[F>>2];dc(k,G,W,V,U,8,0,8,16);break}}else if((p|0)==2){z=b[f+160>>1]|0;A=b[f+162>>1]|0;C=c[f+144>>2]|0;B=a+4|0;o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[B>>2]|0):0)if((c[o>>2]|0)>>>0<6){w=o+172|0;w=e[w>>1]|e[w+2>>1]<<16;m=1;o=c[o+108>>2]|0;r=w&65535;w=w>>>16&65535}else{m=1;o=-1;r=0;w=0}else{m=0;o=-1;r=0;w=0}b:do if((o|0)==(C|0)){n=r;o=w}else{n=c[a+200>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0)if((c[n>>2]|0)>>>0<6){o=n+152|0;o=e[o>>1]|e[o+2>>1]<<16;q=1;s=o&65535;o=o>>>16&65535;p=c[n+104>>2]|0}else{q=1;s=0;o=0;p=-1}else{q=0;s=0;o=0;p=-1}n=c[a+208>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0)if((c[n>>2]|0)>>>0<6){t=n+172|0;n=c[n+108>>2]|0;t=e[t>>1]|e[t+2>>1]<<16}else{n=-1;t=0}else T=54;do if((T|0)==54){n=c[a+212>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0){if((c[n>>2]|0)>>>0>=6){n=-1;t=0;break}t=n+192|0;n=c[n+112>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;break}if((q|0)==0|(m|0)!=0){n=-1;t=0}else{n=s;break b}}while(0);m=(p|0)==(C|0);if((((n|0)==(C|0)&1)+(m&1)|0)==1){if(m){n=m?s:r;o=m?o:w;break}n=t&65535;o=t>>>16&65535;break}n=s<<16>>16;l=r<<16>>16;p=t<<16>>16;if(r<<16>>16>s<<16>>16)m=l;else{m=n;n=(l|0)<(n|0)?l:n}if((m|0)<(p|0))q=m;else q=(n|0)>(p|0)?n:p;n=o<<16>>16;m=w<<16>>16;l=t>>16;if(w<<16>>16>o<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=q&65535;o=o&65535}while(0);n=(n&65535)+(z&65535)|0;o=(o&65535)+(A&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}m=ic(g,C)|0;if(!m){G=1;i=X;return G|0}A=a+132|0;x=a+136|0;y=a+140|0;z=a+144|0;q=a+148|0;p=a+152|0;G=a+156|0;v=a+160|0;b[a+160>>1]=n;b[a+162>>1]=o;v=e[v>>1]|e[v+2>>1]<<16;b[G>>1]=v;b[G+2>>1]=v>>>16;b[p>>1]=v;b[p+2>>1]=v>>>16;b[q>>1]=v;b[q+2>>1]=v>>>16;b[z>>1]=v;b[z+2>>1]=v>>>16;b[y>>1]=v;b[y+2>>1]=v>>>16;b[x>>1]=v;b[x+2>>1]=v>>>16;b[A>>1]=v;b[A+2>>1]=v>>>16;c[a+100>>2]=C;c[a+104>>2]=C;A=a+116|0;c[A>>2]=m;c[a+120>>2]=m;x=b[f+164>>1]|0;y=b[f+166>>1]|0;z=c[f+148>>2]|0;q=c[a+200>>2]|0;p=(q|0)==0;if((!p?(c[q+4>>2]|0)==(c[B>>2]|0):0)?(c[q>>2]|0)>>>0<6:0){w=q+184|0;w=e[w>>1]|e[w+2>>1]<<16;r=w&65535;w=w>>>16&65535;o=c[q+112>>2]|0}else{r=0;w=0;o=-1}do if((o|0)!=(z|0)){s=v&65535;n=v>>>16;u=n&65535;if((!p?(c[q+4>>2]|0)==(c[B>>2]|0):0)?(c[q>>2]|0)>>>0<6:0){t=q+160|0;p=c[q+104>>2]|0;t=e[t>>1]|e[t+2>>1]<<16}else{p=-1;t=0}o=(C|0)==(z|0);if((((p|0)==(z|0)&1)+(o&1)|0)==1){m=o?v:t;o=o?n:t>>>16;break}o=r<<16>>16;p=v<<16>>16;q=t<<16>>16;if(s<<16>>16>r<<16>>16)m=p;else{m=o;o=(p|0)<(o|0)?p:o}if((m|0)>=(q|0))m=(o|0)>(q|0)?o:q;n=w<<16>>16;l=v>>16;p=t>>16;if(u<<16>>16>w<<16>>16)o=l;else{o=n;n=(l|0)<(n|0)?l:n}if((o|0)>=(p|0))o=(n|0)>(p|0)?n:p}else{o=w&65535;m=o<<16|r&65535}while(0);m=(m&65535)+(x&65535)|0;n=(o&65535)+(y&65535)|0;if(((m<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((n<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}o=ic(g,z)|0;if(!o){G=1;i=X;return G|0}else{G=a+164|0;E=a+168|0;D=a+172|0;C=a+176|0;B=a+180|0;y=a+184|0;x=a+188|0;F=a+192|0;b[a+192>>1]=m;b[a+194>>1]=n;F=e[F>>1]|e[F+2>>1]<<16;b[x>>1]=F;b[x+2>>1]=F>>>16;b[y>>1]=F;b[y+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+108>>2]=z;c[a+112>>2]=z;F=a+124|0;c[F>>2]=o;c[a+128>>2]=o;c[W>>2]=c[A>>2];dc(k,a+132|0,W,V,U,0,0,16,8);c[W>>2]=c[F>>2];dc(k,G,W,V,U,0,8,16,8);break}}else{S=a+4|0;H=0;c:while(1){D=f+(H<<2)+176|0;G=eb(c[D>>2]|0)|0;E=f+(H<<2)+192|0;c[a+(H<<2)+100>>2]=c[E>>2];F=ic(g,c[E>>2]|0)|0;c[a+(H<<2)+116>>2]=F;if(!F){l=1;T=212;break}if(G){J=H<<2;K=a+(J<<2)+132|0;O=a+(J<<2)+134|0;P=J|1;L=a+(P<<2)+132|0;P=a+(P<<2)+134|0;Q=J|2;M=a+(Q<<2)+132|0;Q=a+(Q<<2)+134|0;R=J|3;N=a+(R<<2)+132|0;R=a+(R<<2)+134|0;I=0;do{C=b[f+(H<<4)+(I<<2)+208>>1]|0;B=b[f+(H<<4)+(I<<2)+210>>1]|0;F=hb(c[D>>2]|0)|0;n=c[E>>2]|0;s=ub(a,c[6288+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;r=d[6288+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((s|0)!=0?(c[s+4>>2]|0)==(c[S>>2]|0):0)if((c[s>>2]|0)>>>0<6){q=s+(r<<2)+132|0;q=e[q>>1]|e[q+2>>1]<<16;A=c[s+(r>>>2<<2)+100>>2]|0;o=q&65535;z=1;q=q>>>16&65535}else{A=-1;o=0;z=1;q=0}else{A=-1;o=0;z=0;q=0}v=ub(a,c[5776+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;l=d[5776+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((v|0)!=0?(c[v+4>>2]|0)==(c[S>>2]|0):0)if((c[v>>2]|0)>>>0<6){p=v+(l<<2)+132|0;p=e[p>>1]|e[p+2>>1]<<16;y=1;x=c[v+(l>>>2<<2)+100>>2]|0;m=p&65535;p=p>>>16&65535}else{y=1;x=-1;m=0;p=0}else{y=0;x=-1;m=0;p=0}w=ub(a,c[5264+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;v=d[5264+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((w|0)!=0?(c[w+4>>2]|0)==(c[S>>2]|0):0)if((c[w>>2]|0)>>>0<6){z=w+(v<<2)+132|0;z=e[z>>1]|e[z+2>>1]<<16;v=c[w+(v>>>2<<2)+100>>2]|0;T=180}else{z=0;v=-1;T=180}else T=175;do if((T|0)==175){T=0;w=ub(a,c[4752+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;v=d[4752+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((w|0)!=0?(c[w+4>>2]|0)==(c[S>>2]|0):0){if((c[w>>2]|0)>>>0>=6){z=0;v=-1;T=180;break}z=w+(v<<2)+132|0;z=e[z>>1]|e[z+2>>1]<<16;v=c[w+(v>>>2<<2)+100>>2]|0;T=180;break}if((z|0)==0|(y|0)!=0){z=0;v=-1;T=180}else{v=o;t=q}}while(0);do if((T|0)==180){l=(A|0)==(n|0);w=(x|0)==(n|0);if(((w&1)+(l&1)+((v|0)==(n|0)&1)|0)==1){if(l|w){v=l?o:m;t=l?q:p;break}v=z&65535;t=z>>>16&65535;break}u=o<<16>>16;w=m<<16>>16;l=z<<16>>16;if(m<<16>>16>o<<16>>16)v=w;else{v=u;u=(w|0)<(u|0)?w:u}if((v|0)<(l|0))w=v;else w=(u|0)>(l|0)?u:l;t=q<<16>>16;v=p<<16>>16;l=z>>16;if(p<<16>>16>q<<16>>16)s=v;else{s=t;t=(v|0)<(t|0)?v:t}if((s|0)>=(l|0))s=(t|0)>(l|0)?t:l;v=w&65535;t=s&65535}while(0);C=(v&65535)+(C&65535)|0;q=C&65535;s=(t&65535)+(B&65535)|0;r=s&65535;if(((C<<16>>16)+8192|0)>>>0>16383){l=1;T=212;break c}if(((s<<16>>16)+2048|0)>>>0>4095){l=1;T=212;break c}if(!F){b[K>>1]=q;b[O>>1]=r;b[L>>1]=q;b[P>>1]=r;b[M>>1]=q;b[Q>>1]=r;b[N>>1]=q;b[R>>1]=r}else if((F|0)==1){F=(I<<1)+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r;F=F|1;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}else if((F|0)==2){F=I+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r;F=F+2|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}else if((F|0)==3){F=I+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}I=I+1|0}while(I>>>0>>0)}H=H+1|0;if(H>>>0>=4){T=201;break}}if((T|0)==201){o=0;do{c[W>>2]=c[a+(o<<2)+116>>2];m=hb(c[f+(o<<2)+176>>2]|0)|0;l=o<<3&8;n=o>>>0<2?0:8;if(!m)dc(k,a+(o<<2<<2)+132|0,W,V,U,l,n,8,8);else if((m|0)==1){G=o<<2;dc(k,a+(G<<2)+132|0,W,V,U,l,n,8,4);dc(k,a+((G|2)<<2)+132|0,W,V,U,l,n|4,8,4)}else if((m|0)==2){G=o<<2;dc(k,a+(G<<2)+132|0,W,V,U,l,n,4,8);dc(k,a+((G|1)<<2)+132|0,W,V,U,l|4,n,4,8)}else{E=o<<2;dc(k,a+(E<<2)+132|0,W,V,U,l,n,4,4);F=l|4;dc(k,a+((E|1)<<2)+132|0,W,V,U,F,n,4,4);G=n|4;dc(k,a+((E|2)<<2)+132|0,W,V,U,l,G,4,4);dc(k,a+((E|3)<<2)+132|0,W,V,U,F,G,4,4)}o=o+1|0}while((o|0)!=4)}else if((T|0)==212){i=X;return l|0}}while(0);if((c[a+196>>2]|0)>>>0>1){G=0;i=X;return G|0}if(!(c[a>>2]|0)){sc(j,k);G=0;i=X;return G|0}else{tc(j,h,k,f+328|0);G=0;i=X;return G|0}return 0}function Tb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;B=i;i=i+144|0;m=B;if((e|0)>=0?!((e+1+k|0)>>>0>g>>>0|(f|0)<0|(l+f|0)>>>0>h>>>0):0)m=b;else{A=k+1|0;Ub(b,m,e,f,g,h,A,l,A);Ub(b+(Z(h,g)|0)|0,m+(Z(A,l)|0)|0,e,f,g,h,A,l,A);h=l;g=A;e=0;f=0}A=8-j|0;v=l>>>1;z=(v|0)==0;w=k>>>1;y=(w|0)==0;x=16-k|0;u=(g<<1)-k|0;s=g+1|0;t=g+2|0;p=w<<1;r=0;do{l=m+((Z((Z(r,h)|0)+f|0,g)|0)+e)|0;if(!(z|y)){q=c+(r<<6)|0;o=v;while(1){k=q;b=l;n=w;while(1){D=d[b>>0]|0;E=d[b+s>>0]|0;F=b;b=b+2|0;C=d[F+1>>0]|0;a[k+8>>0]=(((Z(E,j)|0)+(Z(d[F+g>>0]|0,A)|0)<<3)+32|0)>>>6;a[k>>0]=(((Z(C,j)|0)+(Z(D,A)|0)<<3)+32|0)>>>6;D=d[b>>0]|0;a[k+9>>0]=(((Z(d[F+t>>0]|0,j)|0)+(Z(E,A)|0)<<3)+32|0)>>>6;a[k+1>>0]=(((Z(D,j)|0)+(Z(C,A)|0)<<3)+32|0)>>>6;n=n+-1|0;if(!n)break;else k=k+2|0}o=o+-1|0;if(!o)break;else{q=q+(p+x)|0;l=l+(p+u)|0}}}r=r+1|0}while((r|0)!=2);i=B;return}function Ub(a,b,c,d,e,f,g,h,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;k=g+c|0;o=h+d|0;s=(c|0)<0|(k|0)>(e|0)?2:1;m=(o|0)<0?0-h|0:d;d=(k|0)<0?0-g|0:c;m=(m|0)>(f|0)?f:m;d=(d|0)>(e|0)?e:d;k=d+g|0;l=m+h|0;if((d|0)>0)a=a+d|0;if((m|0)>0)a=a+(Z(m,e)|0)|0;r=(d|0)<0?0-d|0:0;q=(k|0)>(e|0)?k-e|0:0;p=g-r-q|0;g=0-m|0;m=(m|0)<0?g:0;c=l-f|0;n=(l|0)>(f|0)?c:0;k=h-m|0;d=k-n|0;if(m){m=h+-1-((o|0)>0?o:0)|0;l=~f;l=(m|0)>(l|0)?m:l;m=~l;m=Z(l+((m|0)>0?m:0)+1|0,j)|0;l=b;while(1){xa[s&3](a,l,r,p,q);g=g+-1|0;if(!g)break;else l=l+j|0}b=b+m|0}if((k|0)!=(n|0)){l=h+-1|0;g=l-((o|0)>0?o:0)|0;k=~f;k=(g|0)>(k|0)?g:k;l=l-k|0;g=~k;g=h+f+-1-((l|0)<(f|0)?f:l)-k-((g|0)>0?g:0)|0;k=Z(g,j)|0;g=Z(g,e)|0;l=b;m=a;while(1){xa[s&3](m,l,r,p,q);d=d+-1|0;if(!d)break;else{l=l+j|0;m=m+e|0}}b=b+k|0;a=a+g|0}a=a+(0-e)|0;if(!n){i=t;return}while(1){xa[s&3](a,b,r,p,q);c=c+-1|0;if(!c)break;else b=b+j|0}i=t;return}function Vb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;C=i;i=i+144|0;m=C;if(((e|0)>=0?!((k+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+1+l|0)>>>0<=h>>>0:0)m=b;else{A=l+1|0;Ub(b,m,e,f,g,h,k,A,k);Ub(b+(Z(h,g)|0)|0,m+(Z(A,k)|0)|0,e,f,g,h,k,A,k);h=A;g=k;e=0;f=0}B=8-j|0;w=l>>>1;A=(w|0)==0;x=k>>>1;z=(x|0)==0;y=16-k|0;v=g<<1;u=v-k|0;t=v|1;s=g+1|0;p=x<<1;r=0;do{l=m+((Z((Z(r,h)|0)+f|0,g)|0)+e)|0;if(!(A|z)){q=c+(r<<6)|0;o=w;while(1){k=q;b=l;n=x;while(1){D=d[b+g>>0]|0;E=d[b>>0]|0;a[k+8>>0]=(((Z(D,B)|0)+(Z(d[b+v>>0]|0,j)|0)<<3)+32|0)>>>6;a[k>>0]=(((Z(E,B)|0)+(Z(D,j)|0)<<3)+32|0)>>>6;D=d[b+s>>0]|0;E=d[b+1>>0]|0;a[k+9>>0]=(((Z(D,B)|0)+(Z(d[b+t>>0]|0,j)|0)<<3)+32|0)>>>6;a[k+1>>0]=(((Z(E,B)|0)+(Z(D,j)|0)<<3)+32|0)>>>6;n=n+-1|0;if(!n)break;else{k=k+2|0;b=b+2|0}}o=o+-1|0;if(!o)break;else{q=q+(p+y)|0;l=l+(p+u)|0}}}r=r+1|0}while((r|0)!=2);i=C;return}function Wb(b,c,e,f,g,h,j,k,l,m){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;I=i;i=i+176|0;n=I;if(((e|0)>=0?!((e+1+l|0)>>>0>g>>>0|(f|0)<0):0)?(f+1+m|0)>>>0<=h>>>0:0)n=b;else{B=l+1|0;A=m+1|0;Ub(b,n,e,f,g,h,B,A,B);Ub(b+(Z(h,g)|0)|0,n+(Z(A,B)|0)|0,e,f,g,h,B,A,B);h=A;g=B;e=0;f=0}G=8-j|0;H=8-k|0;B=m>>>1;E=(B|0)==0;A=g<<1;C=l>>>1;F=(C|0)==0;D=16-l|0;z=A-l|0;v=g+1|0;w=A|1;x=g+2|0;y=A+2|0;s=C<<1;u=0;do{l=n+((Z((Z(u,h)|0)+f|0,g)|0)+e)|0;if(!(E|F)){t=c+(u<<6)|0;r=B;while(1){p=d[l+g>>0]|0;m=t;b=l;o=(Z(p,k)|0)+(Z(d[l>>0]|0,H)|0)|0;p=(Z(d[l+A>>0]|0,k)|0)+(Z(p,H)|0)|0;q=C;while(1){K=d[b+v>>0]|0;J=(Z(K,k)|0)+(Z(d[b+1>>0]|0,H)|0)|0;K=(Z(d[b+w>>0]|0,k)|0)+(Z(K,H)|0)|0;M=((Z(o,G)|0)+32+(Z(J,j)|0)|0)>>>6;a[m+8>>0]=((Z(p,G)|0)+32+(Z(K,j)|0)|0)>>>6;a[m>>0]=M;M=b;b=b+2|0;L=d[M+x>>0]|0;o=(Z(L,k)|0)+(Z(d[b>>0]|0,H)|0)|0;p=(Z(d[M+y>>0]|0,k)|0)+(Z(L,H)|0)|0;J=((Z(J,G)|0)+32+(Z(o,j)|0)|0)>>>6;a[m+9>>0]=((Z(K,G)|0)+32+(Z(p,j)|0)|0)>>>6;a[m+1>>0]=J;q=q+-1|0;if(!q)break;else m=m+2|0}r=r+-1|0;if(!r)break;else{t=t+(s+D)|0;l=l+(s+z)|0}}}u=u+1|0}while((u|0)!=2);i=I;return}function Xb(b,c,e,f,g,h,j,k){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;r=i;i=i+448|0;l=r;if(((e|0)>=0?!((j+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)l=b;else{Ub(b,l,e,f,g,h,j,k+5|0,j);g=j;e=0;f=0}h=e+g+(Z(f,g)|0)|0;b=k>>>2;if(!b){i=r;return}n=g<<2;q=0-g|0;o=q<<1;p=g<<1;if(!j){i=r;return}else{m=l+h|0;e=l+(h+(g*5|0))|0}while(1){l=j;h=c;k=m;f=e;while(1){u=d[f+o>>0]|0;v=d[f+q>>0]|0;w=d[f+g>>0]|0;y=d[f>>0]|0;x=w+u|0;s=d[k+p>>0]|0;a[h+48>>0]=a[((d[f+p>>0]|0)+16-x-(x<<2)+s+((y+v|0)*20|0)>>5)+3984>>0]|0;x=s+y|0;t=d[k+g>>0]|0;a[h+32>>0]=a[(w+16-x-(x<<2)+t+((v+u|0)*20|0)>>5)+3984>>0]|0;x=t+v|0;w=d[k>>0]|0;a[h+16>>0]=a[(y+16-x-(x<<2)+w+((s+u|0)*20|0)>>5)+3984>>0]|0;u=w+u|0;a[h>>0]=a[(v+16-u-(u<<2)+(d[k+q>>0]|0)+((t+s|0)*20|0)>>5)+3984>>0]|0;l=l+-1|0;if(!l)break;else{h=h+1|0;k=k+1|0;f=f+1|0}}b=b+-1|0;if(!b)break;else{c=c+64|0;m=m+n|0;e=e+n|0}}i=r;return}function Yb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;v=i;i=i+448|0;m=v;if(((e|0)>=0?!((j+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)m=b;else{Ub(b,m,e,f,g,h,j,k+5|0,j);g=j;e=0;f=0}h=e+g+(Z(f,g)|0)|0;b=k>>>2;if(!b){i=v;return}u=(j|0)==0;s=(g<<2)-j|0;t=64-j|0;r=0-g|0;p=r<<1;q=g<<1;e=m+h|0;f=m+(h+(Z(g,l+2|0)|0))|0;m=m+(h+(g*5|0))|0;while(1){if(u){h=c;k=f}else{k=f+j|0;h=c+j|0;l=j;o=e;n=m;while(1){y=d[n+p>>0]|0;z=d[n+r>>0]|0;A=d[n+g>>0]|0;C=d[n>>0]|0;B=A+y|0;w=d[o+q>>0]|0;a[c+48>>0]=((d[((d[n+q>>0]|0)+16-B-(B<<2)+w+((C+z|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+q>>0]|0)|0)>>>1;B=w+C|0;x=d[o+g>>0]|0;a[c+32>>0]=((d[(A+16-B-(B<<2)+x+((z+y|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+g>>0]|0)|0)>>>1;B=x+z|0;A=d[o>>0]|0;a[c+16>>0]=((d[(C+16-B-(B<<2)+A+((w+y|0)*20|0)>>5)+3984>>0]|0)+1+(d[f>>0]|0)|0)>>>1;y=A+y|0;a[c>>0]=((d[(z+16-y-(y<<2)+(d[o+r>>0]|0)+((x+w|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+r>>0]|0)|0)>>>1;l=l+-1|0;if(!l)break;else{c=c+1|0;o=o+1|0;f=f+1|0;n=n+1|0}}e=e+j|0;m=m+j|0}b=b+-1|0;if(!b)break;else{c=h+t|0;e=e+s|0;f=k+s|0;m=m+s|0}}i=v;return}function Zb(b,c,e,f,g,h,j,k){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;u=i;i=i+448|0;l=u;if((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0|(k+f|0)>>>0>h>>>0):0)l=b;else{n=j+5|0;Ub(b,l,e,f,g,h,n,k,n);g=n;e=0;f=0}if(!k){i=u;return}r=j>>>2;t=(r|0)==0;s=g-j|0;q=16-j|0;p=r<<2;b=c;l=l+(e+5+(Z(f,g)|0))|0;o=k;while(1){if(t)h=b;else{h=b+p|0;e=l;g=d[l+-1>>0]|0;k=d[l+-2>>0]|0;m=d[l+-3>>0]|0;n=d[l+-4>>0]|0;j=d[l+-5>>0]|0;c=r;while(1){f=n+g|0;v=n;n=d[e>>0]|0;a[b>>0]=a[(j+16-f-(f<<2)+n+((m+k|0)*20|0)>>5)+3984>>0]|0;j=n+m|0;f=m;m=d[e+1>>0]|0;a[b+1>>0]=a[(v+16-j-(j<<2)+m+((k+g|0)*20|0)>>5)+3984>>0]|0;j=m+k|0;v=k;k=d[e+2>>0]|0;a[b+2>>0]=a[(f+16-j-(j<<2)+k+((n+g|0)*20|0)>>5)+3984>>0]|0;j=k+g|0;f=d[e+3>>0]|0;a[b+3>>0]=a[(v+16-j-(j<<2)+f+((m+n|0)*20|0)>>5)+3984>>0]|0;c=c+-1|0;if(!c)break;else{j=g;b=b+4|0;e=e+4|0;g=f}}l=l+p|0}o=o+-1|0;if(!o)break;else{b=h+q|0;l=l+s|0}}i=u;return}function _b(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;v=i;i=i+448|0;m=v;if((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0|(k+f|0)>>>0>h>>>0):0)m=b;else{o=j+5|0;Ub(b,m,e,f,g,h,o,k,o);g=o;e=0;f=0}if(!k){i=v;return}s=j>>>2;u=(s|0)==0;t=g-j|0;r=16-j|0;q=(l|0)!=0;p=s<<2;b=c;m=m+(e+5+(Z(f,g)|0))|0;while(1){if(u)h=b;else{h=b+p|0;l=m;e=d[m+-1>>0]|0;g=d[m+-2>>0]|0;n=d[m+-3>>0]|0;o=d[m+-4>>0]|0;j=d[m+-5>>0]|0;c=s;while(1){f=o+e|0;w=o;o=d[l>>0]|0;a[b>>0]=((q?g:n)+1+(d[(j+16-f-(f<<2)+o+((n+g|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=o+n|0;f=n;n=d[l+1>>0]|0;a[b+1>>0]=((q?e:g)+1+(d[(w+16-j-(j<<2)+n+((g+e|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=n+g|0;w=g;g=d[l+2>>0]|0;a[b+2>>0]=((q?o:e)+1+(d[(f+16-j-(j<<2)+g+((o+e|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=g+e|0;f=d[l+3>>0]|0;a[b+3>>0]=((q?n:o)+1+(d[(w+16-j-(j<<2)+f+((n+o|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;c=c+-1|0;if(!c)break;else{j=e;b=b+4|0;l=l+4|0;e=f}}m=m+p|0}k=k+-1|0;if(!k)break;else{b=h+r|0;m=m+t|0}}i=v;return}function $b(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;z=i;i=i+448|0;m=z;if(((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)m=b;else{y=j+5|0;Ub(b,m,e,f,g,h,y,k+5|0,y);g=y;e=0;f=0}b=(Z(f,g)|0)+e|0;y=(l&1|2)+g+b|0;n=m+y|0;if(!k){i=z;return}u=j>>>2;w=(u|0)==0;v=g-j|0;x=16-j|0;t=u<<2;b=m+((Z(g,l>>>1&1|2)|0)+5+b)|0;s=k;while(1){if(!w){r=c+t|0;h=b;e=d[b+-1>>0]|0;f=d[b+-2>>0]|0;o=d[b+-3>>0]|0;p=d[b+-4>>0]|0;l=d[b+-5>>0]|0;q=u;while(1){A=p+e|0;B=p;p=d[h>>0]|0;a[c>>0]=a[(l+16-A-(A<<2)+p+((o+f|0)*20|0)>>5)+3984>>0]|0;A=p+o|0;l=o;o=d[h+1>>0]|0;a[c+1>>0]=a[(B+16-A-(A<<2)+o+((f+e|0)*20|0)>>5)+3984>>0]|0;A=o+f|0;B=f;f=d[h+2>>0]|0;a[c+2>>0]=a[(l+16-A-(A<<2)+f+((p+e|0)*20|0)>>5)+3984>>0]|0;A=f+e|0;l=d[h+3>>0]|0;a[c+3>>0]=a[(B+16-A-(A<<2)+l+((o+p|0)*20|0)>>5)+3984>>0]|0;q=q+-1|0;if(!q)break;else{A=e;c=c+4|0;h=h+4|0;e=l;l=A}}c=r;b=b+t|0}s=s+-1|0;if(!s)break;else{c=c+x|0;b=b+v|0}}b=k>>>2;if(!b){i=z;return}t=(j|0)==0;p=(g<<2)-j|0;o=64-j|0;q=0-g|0;s=q<<1;r=g<<1;c=c+(x-(k<<4))|0;h=m+(y+(g*5|0))|0;l=b;while(1){if(t){b=c;m=n}else{b=c+j|0;m=c;e=n;f=h;c=j;while(1){x=d[f+s>>0]|0;w=d[f+q>>0]|0;u=d[f+g>>0]|0;B=d[f>>0]|0;y=u+x|0;k=d[e+r>>0]|0;A=m+48|0;a[A>>0]=((d[((d[f+r>>0]|0)+16-y-(y<<2)+k+((B+w|0)*20|0)>>5)+3984>>0]|0)+1+(d[A>>0]|0)|0)>>>1;A=k+B|0;y=d[e+g>>0]|0;v=m+32|0;a[v>>0]=((d[(u+16-A-(A<<2)+y+((w+x|0)*20|0)>>5)+3984>>0]|0)+1+(d[v>>0]|0)|0)>>>1;v=d[e>>0]|0;A=y+w|0;u=m+16|0;a[u>>0]=((d[(B+16-A-(A<<2)+v+((k+x|0)*20|0)>>5)+3984>>0]|0)+1+(d[u>>0]|0)|0)>>>1;x=v+x|0;a[m>>0]=((d[(w+16-x-(x<<2)+(d[e+q>>0]|0)+((y+k|0)*20|0)>>5)+3984>>0]|0)+1+(d[m>>0]|0)|0)>>>1;c=c+-1|0;if(!c)break;else{m=m+1|0;e=e+1|0;f=f+1|0}}m=n+j|0;h=h+j|0}l=l+-1|0;if(!l)break;else{c=b+o|0;n=m+p|0;h=h+p|0}}i=z;return}function ac(b,e,f,g,h,j,k,l){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;x=i;i=i+1792|0;m=x+1344|0;w=x;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0){o=l+5|0;m=b;n=f+5|0}else{n=k+5|0;o=l+5|0;Ub(b,m,f,g,h,j,n,o,n);h=n;n=5;g=0}if(o){t=k>>>2;v=(t|0)==0;s=h-k|0;u=t<<2;f=w;m=m+(n+(Z(g,h)|0))|0;while(1){if(v)b=f;else{b=f+(u<<2)|0;g=m;h=d[m+-1>>0]|0;j=d[m+-2>>0]|0;p=d[m+-3>>0]|0;q=d[m+-4>>0]|0;n=d[m+-5>>0]|0;r=t;while(1){y=q+h|0;z=q;q=d[g>>0]|0;c[f>>2]=n-y-(y<<2)+q+((p+j|0)*20|0);y=q+p|0;n=p;p=d[g+1>>0]|0;c[f+4>>2]=z-y+p-(y<<2)+((j+h|0)*20|0);y=p+j|0;z=j;j=d[g+2>>0]|0;c[f+8>>2]=n-y+j-(y<<2)+((q+h|0)*20|0);y=j+h|0;n=d[g+3>>0]|0;c[f+12>>2]=z-y+n-(y<<2)+((p+q|0)*20|0);r=r+-1|0;if(!r)break;else{y=h;f=f+16|0;g=g+4|0;h=n;n=y}}m=m+u|0}o=o+-1|0;if(!o)break;else{f=b;m=m+s|0}}}h=l>>>2;if(!h){i=x;return}u=(k|0)==0;s=64-k|0;p=k*3|0;t=0-k|0;q=t<<1;r=k<<1;g=e;b=w+(k<<2)|0;m=w+(k*6<<2)|0;o=h;while(1){if(u)h=g;else{h=g+k|0;f=b;j=m;n=k;while(1){e=c[j+(q<<2)>>2]|0;w=c[j+(t<<2)>>2]|0;z=c[j+(k<<2)>>2]|0;A=c[j>>2]|0;y=z+e|0;v=c[f+(r<<2)>>2]|0;a[g+48>>0]=a[((c[j+(r<<2)>>2]|0)+512-y-(y<<2)+v+((A+w|0)*20|0)>>10)+3984>>0]|0;y=v+A|0;l=c[f+(k<<2)>>2]|0;a[g+32>>0]=a[(z+512-y-(y<<2)+l+((w+e|0)*20|0)>>10)+3984>>0]|0;y=c[f>>2]|0;z=l+w|0;a[g+16>>0]=a[(A+512-z-(z<<2)+y+((v+e|0)*20|0)>>10)+3984>>0]|0;e=y+e|0;a[g>>0]=a[(w+512-e-(e<<2)+(c[f+(t<<2)>>2]|0)+((l+v|0)*20|0)>>10)+3984>>0]|0;n=n+-1|0;if(!n)break;else{g=g+1|0;f=f+4|0;j=j+4|0}}b=b+(k<<2)|0;m=m+(k<<2)|0}o=o+-1|0;if(!o)break;else{g=h+s|0;b=b+(p<<2)|0;m=m+(p<<2)|0}}i=x;return}function bc(b,e,f,g,h,j,k,l,m){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;y=i;i=i+1792|0;n=y+1344|0;x=y;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0){o=l+5|0;n=b;f=f+5|0}else{q=k+5|0;o=l+5|0;Ub(b,n,f,g,h,j,q,o,q);h=q;f=5;g=0}if(o){v=k>>>2;t=(v|0)==0;u=h-k|0;w=v<<2;p=x;n=n+(f+(Z(g,h)|0))|0;s=o;while(1){if(t)b=p;else{b=p+(w<<2)|0;g=n;f=d[n+-1>>0]|0;h=d[n+-2>>0]|0;j=d[n+-3>>0]|0;q=d[n+-4>>0]|0;o=d[n+-5>>0]|0;r=v;while(1){z=q+f|0;A=q;q=d[g>>0]|0;c[p>>2]=o-z-(z<<2)+q+((j+h|0)*20|0);z=q+j|0;o=j;j=d[g+1>>0]|0;c[p+4>>2]=A-z+j-(z<<2)+((h+f|0)*20|0);z=j+h|0;A=h;h=d[g+2>>0]|0;c[p+8>>2]=o-z+h-(z<<2)+((q+f|0)*20|0);z=h+f|0;o=d[g+3>>0]|0;c[p+12>>2]=A-z+o-(z<<2)+((j+q|0)*20|0);r=r+-1|0;if(!r)break;else{z=f;p=p+16|0;g=g+4|0;f=o;o=z}}n=n+w|0}s=s+-1|0;if(!s)break;else{p=b;n=n+u|0}}}f=l>>>2;if(!f){i=y;return}w=(k|0)==0;u=64-k|0;q=k*3|0;v=0-k|0;t=v<<1;s=k<<1;b=x+(k<<2)|0;n=x+((Z(m+2|0,k)|0)+k<<2)|0;h=x+(k*6<<2)|0;r=f;while(1){if(w){g=e;f=n}else{f=n+(k<<2)|0;g=e+k|0;p=b;j=h;o=k;while(1){m=c[j+(t<<2)>>2]|0;l=c[j+(v<<2)>>2]|0;B=c[j+(k<<2)>>2]|0;C=c[j>>2]|0;A=B+m|0;z=c[p+(s<<2)>>2]|0;a[e+48>>0]=((d[((c[j+(s<<2)>>2]|0)+512-A-(A<<2)+z+((C+l|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(s<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;A=z+C|0;x=c[p+(k<<2)>>2]|0;a[e+32>>0]=((d[(B+512-A-(A<<2)+x+((l+m|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(k<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;A=c[p>>2]|0;B=x+l|0;a[e+16>>0]=((d[(C+512-B-(B<<2)+A+((z+m|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=A+m|0;a[e>>0]=((d[(l+512-m-(m<<2)+(c[p+(v<<2)>>2]|0)+((x+z|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(v<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;o=o+-1|0;if(!o)break;else{e=e+1|0;p=p+4|0;n=n+4|0;j=j+4|0}}b=b+(k<<2)|0;h=h+(k<<2)|0}r=r+-1|0;if(!r)break;else{e=g+u|0;b=b+(q<<2)|0;n=f+(q<<2)|0;h=h+(q<<2)|0}}i=y;return}function cc(b,e,f,g,h,j,k,l,m){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;B=i;i=i+1792|0;n=B+1344|0;A=B;z=k+5|0;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0)n=b;else{Ub(b,n,f,g,h,j,z,l+5|0,z);h=z;f=0;g=0}s=f+h+(Z(g,h)|0)|0;g=l>>>2;if(g){y=(z|0)==0;x=(h<<2)-k+-5|0;t=z*3|0;p=0-h|0;w=p<<1;v=h<<1;u=z<<1;q=-5-k|0;j=A+(z<<2)|0;r=n+s|0;f=n+(s+(h*5|0))|0;while(1){if(y)s=j;else{s=j+(z<<2)|0;n=r;b=f;o=z;while(1){E=d[b+w>>0]|0;F=d[b+p>>0]|0;H=d[b+h>>0]|0;I=d[b>>0]|0;G=H+E|0;C=d[n+v>>0]|0;c[j+(u<<2)>>2]=(d[b+v>>0]|0)-G-(G<<2)+C+((I+F|0)*20|0);G=C+I|0;D=d[n+h>>0]|0;c[j+(z<<2)>>2]=H-G+D-(G<<2)+((F+E|0)*20|0);G=d[n>>0]|0;H=D+F|0;c[j>>2]=I-H+G-(H<<2)+((C+E|0)*20|0);E=G+E|0;c[j+(q<<2)>>2]=F-E+(d[n+p>>0]|0)-(E<<2)+((D+C|0)*20|0);o=o+-1|0;if(!o)break;else{j=j+4|0;n=n+1|0;b=b+1|0}}r=r+z|0;f=f+z|0}g=g+-1|0;if(!g)break;else{j=s+(t<<2)|0;r=r+x|0;f=f+x|0}}}if(!l){i=B;return}v=k>>>2;w=(v|0)==0;u=16-k|0;t=v<<2;h=A+(m+2<<2)|0;g=A+20|0;while(1){if(w)f=h;else{f=h+(t<<2)|0;s=e;n=g;j=c[g+-4>>2]|0;o=c[g+-8>>2]|0;p=c[g+-12>>2]|0;q=c[g+-16>>2]|0;b=c[g+-20>>2]|0;r=v;while(1){m=q+j|0;k=q;q=c[n>>2]|0;a[s>>0]=((d[(b+512-m-(m<<2)+q+((p+o|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=q+p|0;b=p;p=c[n+4>>2]|0;a[s+1>>0]=((d[(k+512-m-(m<<2)+p+((o+j|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+4>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=p+o|0;k=o;o=c[n+8>>2]|0;a[s+2>>0]=((d[(b+512-m-(m<<2)+o+((q+j|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+8>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=o+j|0;b=c[n+12>>2]|0;a[s+3>>0]=((d[(k+512-m-(m<<2)+b+((p+q|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+12>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;r=r+-1|0;if(!r)break;else{m=j;s=s+4|0;h=h+16|0;n=n+16|0;j=b;b=m}}e=e+t|0;g=g+(t<<2)|0}l=l+-1|0;if(!l)break;else{e=e+u|0;h=f+20|0;g=g+20|0}}i=B;return}function dc(a,d,e,f,g,h,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;x=i;q=a+((j<<4)+h)|0;u=b[d>>1]|0;w=d+2|0;t=b[w>>1]|0;s=e+4|0;p=c[s>>2]<<4;r=e+8|0;o=c[r>>2]<<4;f=h+f|0;m=f+(u>>2)|0;g=j+g|0;n=g+(t>>2)|0;do switch(c[6800+((u&3)<<4)+((t&3)<<2)>>2]|0){case 10:{ac(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l);break}case 6:{cc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 4:{_b(c[e>>2]|0,q,m+-2|0,n,p,o,k,l,0);break}case 1:{Yb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l,0);break}case 2:{Xb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l);break}case 12:{_b(c[e>>2]|0,q,m+-2|0,n,p,o,k,l,1);break}case 14:{cc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}case 7:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,2);break}case 13:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}case 5:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 0:{Ub(c[e>>2]|0,q,m,n,p,o,k,l,16);break}case 9:{bc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 8:{Zb(c[e>>2]|0,q,m+-2|0,n,p,o,k,l);break}case 3:{Yb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l,1);break}case 11:{bc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}default:$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,3)}while(0);u=(h>>>1)+256+(j>>>1<<3)|0;v=a+u|0;t=c[e>>2]|0;m=c[s>>2]|0;j=c[r>>2]|0;r=m<<3;s=j<<3;p=b[d>>1]|0;e=(p>>3)+(f>>>1)|0;q=b[w>>1]|0;o=(q>>3)+(g>>>1)|0;p=p&7;q=q&7;g=k>>>1;h=l>>>1;j=Z(m<<8,j)|0;f=t+j|0;m=(p|0)!=0;n=(q|0)!=0;if(m&n){Wb(f,v,e,o,r,s,p,q,g,h);i=x;return}if(m){Tb(f,v,e,o,r,s,p,g,h);i=x;return}if(n){Vb(f,v,e,o,r,s,q,g,h);i=x;return}else{Ub(f,v,e,o,r,s,g,h,8);Ub(t+((Z(s,r)|0)+j)|0,a+(u+64)|0,e,o,r,s,g,h,8);i=x;return}}function ec(b,c,d,e,f){b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0;j=i;if(d){nd(c|0,a[b>>0]|0,d|0)|0;c=c+d|0}if(e){h=c+e|0;g=e;d=b;while(1){a[c>>0]=a[d>>0]|0;g=g+-1|0;if(!g)break;else{c=c+1|0;d=d+1|0}}c=h;b=b+e|0}if(!f){i=j;return}nd(c|0,a[b+-1>>0]|0,f|0)|0;i=j;return}function fc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;c=i;hd(b,a,d);i=c;return}function gc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;f=c[a+40>>2]|0;if(f){h=c[a>>2]|0;k=a+32|0;j=0;do{if(((c[h+(j*40|0)+20>>2]|0)+-1|0)>>>0<2){g=c[h+(j*40|0)+12>>2]|0;if(g>>>0>d>>>0)g=g-(c[k>>2]|0)|0;c[h+(j*40|0)+8>>2]=g}j=j+1|0}while((j|0)!=(f|0))}if(!(c[b>>2]|0)){p=0;i=q;return p|0}g=c[b+4>>2]|0;if(g>>>0>=3){p=0;i=q;return p|0}o=a+32|0;p=a+24|0;n=a+4|0;f=d;m=0;a:while(1){b:do if(g>>>0<2){k=c[b+(m*12|0)+8>>2]|0;if(!g){g=f-k|0;if((g|0)<0)g=(c[o>>2]|0)+g|0}else{l=k+f|0;g=c[o>>2]|0;g=l-((l|0)<(g|0)?0:g)|0}if(g>>>0>d>>>0)f=g-(c[o>>2]|0)|0;else f=g;j=c[p>>2]|0;if(!j){f=1;g=37;break a}k=c[a>>2]|0;l=0;while(1){h=c[k+(l*40|0)+20>>2]|0;if((h+-1|0)>>>0<2?(c[k+(l*40|0)+8>>2]|0)==(f|0):0){f=g;break b}l=l+1|0;if(l>>>0>=j>>>0){f=1;g=37;break a}}}else{j=c[b+(m*12|0)+12>>2]|0;h=c[p>>2]|0;if(!h){f=1;g=37;break a}k=c[a>>2]|0;g=0;while(1){if((c[k+(g*40|0)+20>>2]|0)==3?(c[k+(g*40|0)+8>>2]|0)==(j|0):0){h=3;l=g;break b}g=g+1|0;if(g>>>0>=h>>>0){f=1;g=37;break a}}}while(0);if(!((l|0)>-1&h>>>0>1)){f=1;g=37;break}if(m>>>0>>0){k=e;do{j=k;k=k+-1|0;h=c[n>>2]|0;c[h+(j<<2)>>2]=c[h+(k<<2)>>2]}while(k>>>0>m>>>0);k=c[a>>2]|0}c[(c[n>>2]|0)+(m<<2)>>2]=k+(l*40|0);m=m+1|0;if(m>>>0<=e>>>0){g=m;k=m;do{j=c[n>>2]|0;h=c[j+(g<<2)>>2]|0;if((h|0)!=((c[a>>2]|0)+(l*40|0)|0)){c[j+(k<<2)>>2]=h;k=k+1|0}g=g+1|0}while(g>>>0<=e>>>0)}g=c[b+(m*12|0)+4>>2]|0;if(g>>>0>=3){f=0;g=37;break}}if((g|0)==37){i=q;return f|0}return 0}function hc(a,b,d,e,f,g,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0;K=i;I=c[d>>2]|0;J=c[a+8>>2]|0;if((I|0)!=(c[J>>2]|0)){D=1;i=K;return D|0}B=a+52|0;c[B>>2]=0;G=c[a+56>>2]|0;o=(G|0)==0;H=o&1;do if(!b){c[J+20>>2]=0;c[J+12>>2]=e;c[J+8>>2]=e;c[J+16>>2]=f;c[J+24>>2]=H;if(o){d=a+44|0;c[d>>2]=(c[d>>2]|0)+1;d=0;r=0}else{d=G;r=0}}else{if(g){k=a+20|0;c[k>>2]=0;l=a+16|0;c[l>>2]=0;r=c[a>>2]|0;s=a+44|0;q=0;do{p=r+(q*40|0)+20|0;if((c[p>>2]|0)!=0?(c[p>>2]=0,(c[r+(q*40|0)+24>>2]|0)==0):0)c[s>>2]=(c[s>>2]|0)+-1;q=q+1|0}while((q|0)!=16);a:do if(o){n=c[a+28>>2]|0;m=a+12|0;q=0;while(1){e=0;p=2147483647;o=0;do{if(c[r+(e*40|0)+24>>2]|0){C=c[r+(e*40|0)+16>>2]|0;D=(C|0)<(p|0);p=D?C:p;o=D?r+(e*40|0)|0:o}e=e+1|0}while(e>>>0<=n>>>0);if(!o){d=0;break a}D=c[m>>2]|0;c[D+(q<<4)>>2]=c[o>>2];c[D+(q<<4)+12>>2]=c[o+36>>2];c[D+(q<<4)+4>>2]=c[o+28>>2];c[D+(q<<4)+8>>2]=c[o+32>>2];q=q+1|0;c[l>>2]=q;c[o+24>>2]=0;if(c[o+20>>2]|0)continue;c[s>>2]=(c[s>>2]|0)+-1}}else d=G;while(0);p=a+40|0;c[p>>2]=0;o=a+36|0;c[o>>2]=65535;c[a+48>>2]=0;if(!(c[b>>2]|d))d=0;else{c[l>>2]=0;c[k>>2]=0}r=(c[b+4>>2]|0)==0;c[J+20>>2]=r?2:3;c[o>>2]=r?65535:0;c[J+12>>2]=0;c[J+8>>2]=0;c[J+16>>2]=0;c[J+24>>2]=H;c[s>>2]=1;c[p>>2]=1;r=0;break}if(!(c[b+8>>2]|0)){d=a+40|0;q=c[d>>2]|0;p=c[a+24>>2]|0;if(q>>>0>=p>>>0)if(q){l=c[a>>2]|0;m=0;o=-1;n=0;do{if(((c[l+(m*40|0)+20>>2]|0)+-1|0)>>>0<2){D=c[l+(m*40|0)+8>>2]|0;C=(D|0)<(n|0)|(o|0)==-1;o=C?m:o;n=C?D:n}m=m+1|0}while((m|0)!=(q|0));if((o|0)>-1){q=q+-1|0;c[l+(o*40|0)+20>>2]=0;c[d>>2]=q;if(!(c[l+(o*40|0)+24>>2]|0)){d=a+44|0;c[d>>2]=(c[d>>2]|0)+-1;d=G;n=0}else{d=G;n=0}}else{d=G;n=1}}else{q=0;d=G;n=1}else{d=G;n=0}}else{E=a+24|0;C=a+40|0;v=a+44|0;x=a+36|0;A=a+48|0;u=a+28|0;y=a+16|0;z=a+12|0;r=G;d=G;t=0;w=0;b:while(1){switch(c[b+(t*20|0)+12>>2]|0){case 4:{l=c[b+(t*20|0)+28>>2]|0;c[x>>2]=l;m=c[E>>2]|0;if(!m)s=w;else{n=c[a>>2]|0;s=l;o=0;do{k=n+(o*40|0)+20|0;do if((c[k>>2]|0)==3){if((c[n+(o*40|0)+8>>2]|0)>>>0<=l>>>0)if((s|0)==65535)s=65535;else break;c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[n+(o*40|0)+24>>2]|0))c[v>>2]=(c[v>>2]|0)+-1}while(0);o=o+1|0}while((o|0)!=(m|0));s=w}break}case 1:{n=e-(c[b+(t*20|0)+16>>2]|0)|0;l=c[E>>2]|0;if(!l){n=1;break b}m=c[a>>2]|0;s=0;while(1){k=m+(s*40|0)+20|0;if(((c[k>>2]|0)+-1|0)>>>0<2?(c[m+(s*40|0)+8>>2]|0)==(n|0):0)break;s=s+1|0;if(s>>>0>=l>>>0){n=1;break b}}if((s|0)<0){n=1;break b}c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[m+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=w}else s=w;break}case 6:{m=c[b+(t*20|0)+24>>2]|0;s=c[x>>2]|0;if((s|0)==65535|s>>>0>>0){n=1;F=101;break b}r=c[E>>2]|0;c:do if(r){l=c[a>>2]|0;s=0;while(1){k=l+(s*40|0)+20|0;if((c[k>>2]|0)==3?(c[l+(s*40|0)+8>>2]|0)==(m|0):0)break;s=s+1|0;if(s>>>0>=r>>>0){F=88;break c}}c[k>>2]=0;k=(c[C>>2]|0)+-1|0;c[C>>2]=k;if(!(c[l+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=k}else s=k}else{r=0;F=88}while(0);if((F|0)==88){F=0;s=c[C>>2]|0}if(s>>>0>=r>>>0){n=1;F=101;break b}c[J+12>>2]=e;c[J+8>>2]=m;c[J+16>>2]=f;c[J+20>>2]=3;c[J+24>>2]=H;c[C>>2]=s+1;c[v>>2]=(c[v>>2]|0)+1;r=G;d=G;s=1;break}case 2:{l=c[b+(t*20|0)+20>>2]|0;m=c[E>>2]|0;if(!m){n=1;break b}n=c[a>>2]|0;s=0;while(1){k=n+(s*40|0)+20|0;if((c[k>>2]|0)==3?(c[n+(s*40|0)+8>>2]|0)==(l|0):0)break;s=s+1|0;if(s>>>0>=m>>>0){n=1;break b}}if((s|0)<0){n=1;break b}c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[n+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=w}else s=w;break}case 3:{s=c[b+(t*20|0)+16>>2]|0;n=c[b+(t*20|0)+24>>2]|0;k=c[x>>2]|0;if((k|0)==65535|k>>>0>>0){n=1;break b}o=c[E>>2]|0;if(!o){n=1;break b}p=c[a>>2]|0;k=0;while(1){m=p+(k*40|0)+20|0;if((c[m>>2]|0)==3?(c[p+(k*40|0)+8>>2]|0)==(n|0):0){F=47;break}l=k+1|0;if(l>>>0>>0)k=l;else break}if((F|0)==47?(F=0,c[m>>2]=0,c[C>>2]=(c[C>>2]|0)+-1,(c[p+(k*40|0)+24>>2]|0)==0):0)c[v>>2]=(c[v>>2]|0)+-1;m=e-s|0;s=0;while(1){l=p+(s*40|0)+20|0;k=c[l>>2]|0;if((k+-1|0)>>>0<2?(D=p+(s*40|0)+8|0,(c[D>>2]|0)==(m|0)):0)break;s=s+1|0;if(s>>>0>=o>>>0){n=1;break b}}if(!((s|0)>-1&k>>>0>1)){n=1;break b}c[l>>2]=3;c[D>>2]=n;s=w;break}case 5:{n=c[a>>2]|0;q=0;do{p=n+(q*40|0)+20|0;if((c[p>>2]|0)!=0?(c[p>>2]=0,(c[n+(q*40|0)+24>>2]|0)==0):0)c[v>>2]=(c[v>>2]|0)+-1;q=q+1|0}while((q|0)!=16);d:do if(!d){l=c[u>>2]|0;m=r;while(1){d=0;s=2147483647;k=0;do{if(c[n+(d*40|0)+24>>2]|0){o=c[n+(d*40|0)+16>>2]|0;e=(o|0)<(s|0);s=e?o:s;k=e?n+(d*40|0)|0:k}d=d+1|0}while(d>>>0<=l>>>0);if(!k){r=m;d=0;break d}s=c[y>>2]|0;d=c[z>>2]|0;c[d+(s<<4)>>2]=c[k>>2];c[d+(s<<4)+12>>2]=c[k+36>>2];c[d+(s<<4)+4>>2]=c[k+28>>2];c[d+(s<<4)+8>>2]=c[k+32>>2];c[y>>2]=s+1;c[k+24>>2]=0;if(!(c[k+20>>2]|0))c[v>>2]=(c[v>>2]|0)+-1;if(!m)m=0;else{r=m;d=m;break}}}while(0);c[C>>2]=0;c[x>>2]=65535;c[A>>2]=0;c[B>>2]=1;e=0;s=w;break}case 0:{n=0;F=101;break b}default:{n=1;break b}}t=t+1|0;w=s}if(w){r=n;break}q=c[C>>2]|0;p=c[E>>2]|0}if(q>>>0

>>0){c[J+12>>2]=e;c[J+8>>2]=e;c[J+16>>2]=f;c[J+20>>2]=2;c[J+24>>2]=H;r=a+44|0;c[r>>2]=(c[r>>2]|0)+1;c[a+40>>2]=q+1;r=n}else r=1}while(0);c[J+36>>2]=g;c[J+28>>2]=h;c[J+32>>2]=j;if(!d){o=a+44|0;d=c[o>>2]|0;k=c[a+28>>2]|0;if(d>>>0>k>>>0){p=a+16|0;q=a+12|0;do{n=c[a>>2]|0;e=0;l=2147483647;m=0;do{if(c[n+(e*40|0)+24>>2]|0){C=c[n+(e*40|0)+16>>2]|0;D=(C|0)<(l|0);l=D?C:l;m=D?n+(e*40|0)|0:m}e=e+1|0}while(e>>>0<=k>>>0);if((m|0)!=0?(D=c[p>>2]|0,C=c[q>>2]|0,c[C+(D<<4)>>2]=c[m>>2],c[C+(D<<4)+12>>2]=c[m+36>>2],c[C+(D<<4)+4>>2]=c[m+28>>2],c[C+(D<<4)+8>>2]=c[m+32>>2],c[p>>2]=D+1,c[m+24>>2]=0,(c[m+20>>2]|0)==0):0){d=d+-1|0;c[o>>2]=d}}while(d>>>0>k>>>0)}}else{k=a+16|0;D=c[k>>2]|0;C=c[a+12>>2]|0;c[C+(D<<4)>>2]=I;c[C+(D<<4)+12>>2]=g;c[C+(D<<4)+4>>2]=h;c[C+(D<<4)+8>>2]=j;c[k>>2]=D+1;k=c[a+28>>2]|0}rc(c[a>>2]|0,k+1|0);D=r;i=K;return D|0}function ic(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;if((b>>>0<=16?(d=c[(c[a+4>>2]|0)+(b<<2)>>2]|0,(d|0)!=0):0)?(c[d+20>>2]|0)>>>0>1:0)d=c[d>>2]|0;else d=0;i=e;return d|0}function jc(a){a=a|0;var b=0;b=(c[a>>2]|0)+((c[a+28>>2]|0)*40|0)|0;c[a+8>>2]=b;return c[b>>2]|0}function kc(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0;j=i;c[a+36>>2]=65535;e=e>>>0>1?e:1;c[a+24>>2]=e;h=a+28|0;c[h>>2]=(g|0)==0?d:e;c[a+32>>2]=f;c[a+56>>2]=g;c[a+44>>2]=0;c[a+40>>2]=0;c[a+48>>2]=0;g=fd(680)|0;c[a>>2]=g;if(!g){g=65535;i=j;return g|0}id(g,0,680);a:do if((c[h>>2]|0)!=-1){f=b*384|47;e=0;while(1){d=fd(f)|0;g=c[a>>2]|0;c[g+(e*40|0)+4>>2]=d;if(!d){g=65535;break}c[g+(e*40|0)>>2]=d+(0-d&15);e=e+1|0;if(e>>>0>=((c[h>>2]|0)+1|0)>>>0)break a}i=j;return g|0}while(0);g=a+4|0;c[g>>2]=fd(68)|0;f=fd((c[h>>2]<<4)+16|0)|0;c[a+12>>2]=f;g=c[g>>2]|0;if((g|0)==0|(f|0)==0){g=65535;i=j;return g|0}id(g,0,68);c[a+20>>2]=0;c[a+16>>2]=0;g=0;i=j;return g|0}function lc(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0;l=i;h=c[a>>2]|0;if(h){k=a+28|0;if((c[k>>2]|0)!=-1){j=0;do{gd(c[h+(j*40|0)+4>>2]|0);h=c[a>>2]|0;c[h+(j*40|0)+4>>2]=0;j=j+1|0}while(j>>>0<((c[k>>2]|0)+1|0)>>>0)}}else h=0;gd(h);c[a>>2]=0;h=a+4|0;gd(c[h>>2]|0);c[h>>2]=0;h=a+12|0;gd(c[h>>2]|0);c[h>>2]=0;h=kc(a,b,d,e,f,g)|0;i=l;return h|0}function mc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;b=c[a>>2]|0;if(b){e=a+28|0;if((c[e>>2]|0)!=-1){d=0;do{gd(c[b+(d*40|0)+4>>2]|0);b=c[a>>2]|0;c[b+(d*40|0)+4>>2]=0;d=d+1|0}while(d>>>0<((c[e>>2]|0)+1|0)>>>0)}}else b=0;gd(b);c[a>>2]=0;b=a+4|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+12|0;gd(c[b>>2]|0);c[b>>2]=0;i=f;return}function nc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;b=c[a+40>>2]|0;if(!b){i=f;return}e=a+4|0;d=0;do{c[(c[e>>2]|0)+(d<<2)>>2]=(c[a>>2]|0)+(d*40|0);d=d+1|0}while(d>>>0>>0);i=f;return}function oc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;y=i;v=a+16|0;c[v>>2]=0;c[a+20>>2]=0;if(!e){b=0;i=y;return b|0}x=a+48|0;e=c[x>>2]|0;f=(e|0)==(b|0);a:do if(!f?(u=a+32|0,l=c[u>>2]|0,k=((e+1|0)>>>0)%(l>>>0)|0,(k|0)!=(b|0)):0){t=a+28|0;w=c[(c[a>>2]|0)+((c[t>>2]|0)*40|0)>>2]|0;r=a+40|0;p=a+24|0;o=a+44|0;q=a+56|0;s=a+12|0;n=k;while(1){k=c[r>>2]|0;if(!k)k=0;else{j=c[a>>2]|0;h=0;do{if(((c[j+(h*40|0)+20>>2]|0)+-1|0)>>>0<2){e=c[j+(h*40|0)+12>>2]|0;c[j+(h*40|0)+8>>2]=e-(e>>>0>n>>>0?l:0)}h=h+1|0}while((h|0)!=(k|0))}if(k>>>0>=(c[p>>2]|0)>>>0){if(!k){e=1;g=46;break}f=c[a>>2]|0;h=0;l=-1;j=0;while(1){if(((c[f+(h*40|0)+20>>2]|0)+-1|0)>>>0<2){e=c[f+(h*40|0)+8>>2]|0;m=(e|0)<(j|0)|(l|0)==-1;g=m?h:l;j=m?e:j}else g=l;h=h+1|0;if((h|0)==(k|0))break;else l=g}if((g|0)<=-1){e=1;g=46;break}l=k+-1|0;c[f+(g*40|0)+20>>2]=0;c[r>>2]=l;if(!(c[f+(g*40|0)+24>>2]|0)){c[o>>2]=(c[o>>2]|0)+-1;k=l}else k=l}l=c[o>>2]|0;m=c[t>>2]|0;if(l>>>0>=m>>>0){e=(c[q>>2]|0)==0;do if(e){g=c[a>>2]|0;f=0;j=2147483647;h=0;do{if(c[g+(f*40|0)+24>>2]|0){A=c[g+(f*40|0)+16>>2]|0;z=(A|0)<(j|0);j=z?A:j;h=z?g+(f*40|0)|0:h}f=f+1|0}while(f>>>0<=m>>>0);if((h|0)!=0?(f=c[v>>2]|0,g=c[s>>2]|0,c[g+(f<<4)>>2]=c[h>>2],c[g+(f<<4)+12>>2]=c[h+36>>2],c[g+(f<<4)+4>>2]=c[h+28>>2],c[g+(f<<4)+8>>2]=c[h+32>>2],c[v>>2]=f+1,c[h+24>>2]=0,(c[h+20>>2]|0)==0):0){l=l+-1|0;c[o>>2]=l}}while(l>>>0>=m>>>0)}e=c[a>>2]|0;c[e+(m*40|0)+20>>2]=1;c[e+(m*40|0)+12>>2]=n;c[e+(m*40|0)+8>>2]=n;c[e+(m*40|0)+16>>2]=0;c[e+(m*40|0)+24>>2]=0;c[o>>2]=l+1;c[r>>2]=k+1;rc(e,m+1|0);l=c[u>>2]|0;n=((n+1|0)>>>0)%(l>>>0)|0;if((n|0)==(b|0)){g=31;break}}if((g|0)==31){g=c[v>>2]|0;if(!g){g=41;break}e=c[s>>2]|0;h=c[t>>2]|0;j=c[a>>2]|0;l=j+(h*40|0)|0;k=c[l>>2]|0;f=0;while(1){if((c[e+(f<<4)>>2]|0)==(k|0))break;f=f+1|0;if(f>>>0>=g>>>0){g=41;break a}}if(!h){g=41;break}else e=0;while(1){f=j+(e*40|0)|0;e=e+1|0;if((c[f>>2]|0)==(w|0))break;if(e>>>0>=h>>>0){g=41;break a}}c[f>>2]=k;c[l>>2]=w;g=41;break}else if((g|0)==46){i=y;return e|0}}else g=39;while(0);if((g|0)==39)if(d)if(f){b=1;i=y;return b|0}else g=41;do if((g|0)==41){if(!d){e=c[x>>2]|0;break}c[x>>2]=b;b=0;i=y;return b|0}while(0);if((e|0)==(b|0)){b=0;i=y;return b|0}a=c[a+32>>2]|0;c[x>>2]=((b+-1+a|0)>>>0)%(a>>>0)|0;b=0;i=y;return b|0}function pc(a){a=a|0;var b=0,d=0,e=0;e=i;d=a+20|0;b=c[d>>2]|0;if(b>>>0>=(c[a+16>>2]|0)>>>0){b=0;i=e;return b|0}a=c[a+12>>2]|0;c[d>>2]=b+1;b=a+(b<<4)|0;i=e;return b|0}function qc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;k=i;f=c[a>>2]|0;if(!f){i=k;return}c[a+60>>2]=1;if(c[a+56>>2]|0){i=k;return}g=c[a+28>>2]|0;h=a+16|0;j=a+12|0;e=a+44|0;a=0;b=2147483647;d=0;while(1){if(c[f+(a*40|0)+24>>2]|0){m=c[f+(a*40|0)+16>>2]|0;l=(m|0)<(b|0);b=l?m:b;d=l?f+(a*40|0)|0:d}a=a+1|0;if(a>>>0<=g>>>0)continue;if(!d)break;l=c[h>>2]|0;b=c[j>>2]|0;c[b+(l<<4)>>2]=c[d>>2];c[b+(l<<4)+12>>2]=c[d+36>>2];c[b+(l<<4)+4>>2]=c[d+28>>2];c[b+(l<<4)+8>>2]=c[d+32>>2];c[h>>2]=l+1;c[d+24>>2]=0;if(c[d+20>>2]|0){a=0;b=2147483647;d=0;continue}c[e>>2]=(c[e>>2]|0)+-1;a=0;b=2147483647;d=0}i=k;return}function rc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=i;i=i+32|0;q=v+16|0;t=v;o=7;do{if(o>>>0>>0){n=o;do{m=a+(n*40|0)|0;l=c[m>>2]|0;m=c[m+4>>2]|0;p=c[a+(n*40|0)+8>>2]|0;k=a+(n*40|0)+12|0;s=c[k+4>>2]|0;r=q;c[r>>2]=c[k>>2];c[r+4>>2]=s;r=c[a+(n*40|0)+20>>2]|0;s=c[a+(n*40|0)+24>>2]|0;k=a+(n*40|0)+28|0;c[t+0>>2]=c[k+0>>2];c[t+4>>2]=c[k+4>>2];c[t+8>>2]=c[k+8>>2];a:do if(n>>>0>>0){d=n;u=8}else{f=(s|0)==0;j=r+-1|0;k=j>>>0<2;b:do if(!r){e=n;while(1){d=e-o|0;if(c[a+(d*40|0)+20>>2]|0){d=e;break b}if((c[a+(d*40|0)+24>>2]|0)!=0|f){d=e;break b}e=a+(e*40|0)+0|0;g=a+(d*40|0)+0|0;h=e+40|0;do{c[e>>2]=c[g>>2];e=e+4|0;g=g+4|0}while((e|0)<(h|0));if(d>>>0>>0){u=8;break a}else e=d}}else{d=n;while(1){f=d-o|0;e=c[a+(f*40|0)+20>>2]|0;do if(e){e=e+-1|0;if((e|j)>>>0<2){e=c[a+(f*40|0)+8>>2]|0;if((e|0)>(p|0))break b;d=a+(d*40|0)|0;if((e|0)<(p|0))break;else break a}if(e>>>0<2)break b;if(!k?(c[a+(f*40|0)+8>>2]|0)<=(p|0):0)break b;else u=16}else u=16;while(0);if((u|0)==16){u=0;d=a+(d*40|0)|0}e=d+0|0;g=a+(f*40|0)+0|0;h=e+40|0;do{c[e>>2]=c[g>>2];e=e+4|0;g=g+4|0}while((e|0)<(h|0));if(f>>>0>>0){d=f;u=8;break a}else d=f}}while(0);d=a+(d*40|0)|0}while(0);if((u|0)==8){u=0;d=a+(d*40|0)|0}k=d;c[k>>2]=l;c[k+4>>2]=m;c[d+8>>2]=p;k=q;l=c[k+4>>2]|0;m=d+12|0;c[m>>2]=c[k>>2];c[m+4>>2]=l;c[d+20>>2]=r;c[d+24>>2]=s;m=d+28|0;c[m+0>>2]=c[t+0>>2];c[m+4>>2]=c[t+4>>2];c[m+8>>2]=c[t+8>>2];n=n+1|0}while((n|0)!=(b|0))}o=o>>>1}while((o|0)!=0);i=v;return}function sc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;e=c[a+4>>2]|0;f=c[a+16>>2]|0;g=c[a+20>>2]|0;j=e<<2;k=b+256|0;h=16;a=c[a+12>>2]|0;d=b;while(1){m=c[d+4>>2]|0;c[a>>2]=c[d>>2];c[a+4>>2]=m;m=c[d+12>>2]|0;c[a+8>>2]=c[d+8>>2];c[a+12>>2]=m;h=h+-1|0;if(!h)break;else{a=a+(j<<2)|0;d=d+16|0}}j=e<<1&2147483646;h=c[b+260>>2]|0;c[f>>2]=c[k>>2];c[f+4>>2]=h;k=c[b+268>>2]|0;c[f+(j<<2)>>2]=c[b+264>>2];c[f+((j|1)<<2)>>2]=k;k=e<<2;h=c[b+276>>2]|0;c[f+(k<<2)>>2]=c[b+272>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+284>>2]|0;c[f+(k<<2)>>2]=c[b+280>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+292>>2]|0;c[f+(k<<2)>>2]=c[b+288>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+300>>2]|0;c[f+(k<<2)>>2]=c[b+296>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+308>>2]|0;c[f+(k<<2)>>2]=c[b+304>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+316>>2]|0;c[f+(k<<2)>>2]=c[b+312>>2];c[f+((k|1)<<2)>>2]=h;k=c[b+324>>2]|0;c[g>>2]=c[b+320>>2];c[g+4>>2]=k;k=c[b+332>>2]|0;c[g+(j<<2)>>2]=c[b+328>>2];c[g+((j|1)<<2)>>2]=k;k=e<<2;h=c[b+340>>2]|0;c[g+(k<<2)>>2]=c[b+336>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+348>>2]|0;c[g+(k<<2)>>2]=c[b+344>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+356>>2]|0;c[g+(k<<2)>>2]=c[b+352>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+364>>2]|0;c[g+(k<<2)>>2]=c[b+360>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+372>>2]|0;c[g+(k<<2)>>2]=c[b+368>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;j=c[b+380>>2]|0;c[g+(k<<2)>>2]=c[b+376>>2];c[g+((k|1)<<2)>>2]=j;i=l;return}function tc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;y=i;r=c[b+4>>2]|0;s=Z(c[b+8>>2]|0,r)|0;w=(e>>>0)%(r>>>0)|0;x=c[b>>2]|0;u=e-w|0;b=(u<<8)+(w<<4)|0;v=s<<8;w=w<<3;p=r<<4;o=r<<2&1073741820;l=o<<1;m=l+o|0;n=0;do{k=c[3344+(n<<2)>>2]|0;j=c[3408+(n<<2)>>2]|0;e=(j<<4)+k|0;h=f+e|0;j=b+k+(Z(j,p)|0)|0;k=x+j|0;q=c[g+(n<<6)>>2]|0;if((q|0)==16777215){j=c[f+(e+16)>>2]|0;c[k>>2]=c[h>>2];c[k+(o<<2)>>2]=j;j=c[f+(e+48)>>2]|0;c[k+(l<<2)>>2]=c[f+(e+32)>>2];c[k+(m<<2)>>2]=j}else{A=d[f+(e+1)>>0]|0;z=c[g+(n<<6)+4>>2]|0;a[k>>0]=a[3472+(q+512+(d[h>>0]|0))>>0]|0;q=d[f+(e+2)>>0]|0;t=c[g+(n<<6)+8>>2]|0;a[x+(j+1)>>0]=a[3472+((A|512)+z)>>0]|0;k=d[f+(e+3)>>0]|0;h=c[g+(n<<6)+12>>2]|0;a[x+(j+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(j+3)>>0]=a[3472+(h+512+k)>>0]|0;k=j+p|0;h=d[f+(e+17)>>0]|0;j=c[g+(n<<6)+20>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+16>>2]|0)+512+(d[f+(e+16)>>0]|0))>>0]|0;q=d[f+(e+18)>>0]|0;t=c[g+(n<<6)+24>>2]|0;a[x+(k+1)>>0]=a[3472+((h|512)+j)>>0]|0;j=d[f+(e+19)>>0]|0;h=c[g+(n<<6)+28>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(h+512+j)>>0]|0;k=k+p|0;j=d[f+(e+33)>>0]|0;h=c[g+(n<<6)+36>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+32>>2]|0)+512+(d[f+(e+32)>>0]|0))>>0]|0;q=d[f+(e+34)>>0]|0;t=c[g+(n<<6)+40>>2]|0;a[x+(k+1)>>0]=a[3472+((j|512)+h)>>0]|0;h=d[f+(e+35)>>0]|0;j=c[g+(n<<6)+44>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(j+512+h)>>0]|0;k=k+p|0;h=d[f+(e+49)>>0]|0;j=c[g+(n<<6)+52>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+48>>2]|0)+512+(d[f+(e+48)>>0]|0))>>0]|0;q=d[f+(e+50)>>0]|0;t=c[g+(n<<6)+56>>2]|0;a[x+(k+1)>>0]=a[3472+((h|512)+j)>>0]|0;j=d[f+(e+51)>>0]|0;h=c[g+(n<<6)+60>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(h+512+j)>>0]|0}n=n+1|0}while((n|0)!=16);t=s<<6;s=r<<3&2147483640;r=f+256|0;f=f+320|0;l=w+v+(u<<6)|0;p=s>>>2;j=s>>>1;k=j+p|0;o=16;do{q=o&3;h=c[3344+(q<<2)>>2]|0;q=c[3408+(q<<2)>>2]|0;e=o>>>0>19;m=e?f:r;n=(q<<3)+h|0;b=m+n|0;q=l+(e?t:0)+h+(Z(q,s)|0)|0;h=x+q|0;e=c[g+(o<<6)>>2]|0;if((e|0)==16777215){z=c[m+(n+8)>>2]|0;c[h>>2]=c[b>>2];c[h+(p<<2)>>2]=z;z=c[m+(n+24)>>2]|0;c[h+(j<<2)>>2]=c[m+(n+16)>>2];c[h+(k<<2)>>2]=z}else{v=d[m+(n+1)>>0]|0;z=c[g+(o<<6)+4>>2]|0;a[h>>0]=a[3472+(e+512+(d[b>>0]|0))>>0]|0;w=d[m+(n+2)>>0]|0;u=c[g+(o<<6)+8>>2]|0;a[x+(q+1)>>0]=a[3472+((v|512)+z)>>0]|0;z=d[m+(n+3)>>0]|0;v=c[g+(o<<6)+12>>2]|0;a[x+(q+2)>>0]=a[3472+(u+512+w)>>0]|0;a[x+(q+3)>>0]=a[3472+(v+512+z)>>0]|0;z=q+s|0;v=d[m+(n+9)>>0]|0;w=c[g+(o<<6)+20>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+16>>2]|0)+512+(d[m+(n+8)>>0]|0))>>0]|0;u=d[m+(n+10)>>0]|0;q=c[g+(o<<6)+24>>2]|0;a[x+(z+1)>>0]=a[3472+((v|512)+w)>>0]|0;w=d[m+(n+11)>>0]|0;v=c[g+(o<<6)+28>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(v+512+w)>>0]|0;z=z+s|0;w=d[m+(n+17)>>0]|0;v=c[g+(o<<6)+36>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+32>>2]|0)+512+(d[m+(n+16)>>0]|0))>>0]|0;u=d[m+(n+18)>>0]|0;q=c[g+(o<<6)+40>>2]|0;a[x+(z+1)>>0]=a[3472+((w|512)+v)>>0]|0;v=d[m+(n+19)>>0]|0;w=c[g+(o<<6)+44>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(w+512+v)>>0]|0;z=z+s|0;v=d[m+(n+25)>>0]|0;w=c[g+(o<<6)+52>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+48>>2]|0)+512+(d[m+(n+24)>>0]|0))>>0]|0;u=d[m+(n+26)>>0]|0;q=c[g+(o<<6)+56>>2]|0;a[x+(z+1)>>0]=a[3472+((v|512)+w)>>0]|0;w=d[m+(n+27)>>0]|0;v=c[g+(o<<6)+60>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(v+512+w)>>0]|0}o=o+1|0}while((o|0)!=24);i=y;return}function uc(e,f){e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0;bb=i;i=i+176|0;ia=bb+40|0;La=bb;ea=c[e+4>>2]|0;ka=e+8|0;Wa=c[ka>>2]|0;g=Z(Wa,ea)|0;if(!Wa){i=bb;return}Za=ia+24|0;_a=ia+16|0;$a=ia+8|0;la=ia+100|0;ma=ia+68|0;na=ia+36|0;oa=ia+4|0;Ma=ia+120|0;Na=ia+112|0;Pa=ia+104|0;Qa=ia+96|0;Ra=ia+88|0;Sa=ia+80|0;Ta=ia+72|0;Ua=ia+64|0;Va=ia+56|0;Wa=ia+48|0;Xa=ia+40|0;Ya=ia+32|0;pa=ia+124|0;qa=ia+116|0;ra=ia+108|0;sa=ia+92|0;ta=ia+84|0;ua=ia+76|0;va=ia+60|0;wa=ia+52|0;xa=ia+44|0;ya=ia+28|0;za=ia+20|0;Aa=ia+12|0;ha=La+28|0;ja=La+32|0;Ka=La+24|0;Da=ea<<4;Ja=0-Da|0;Ca=Ja<<1;Ha=Z(ea,-48)|0;Ia=ea<<5;Ea=Ja<<2;Ga=ea*48|0;Ba=ea<<6;ga=La+24|0;fa=La+12|0;Fa=g<<8;ba=g<<6;ca=ea<<3;W=Da|4;Y=La+16|0;$=La+20|0;da=La+12|0;X=La+4|0;_=La+8|0;U=0;aa=0;V=f;while(1){f=c[V+8>>2]|0;do if((f|0)!=1){T=V+200|0;n=c[T>>2]|0;do if(!n)g=1;else{if((f|0)==2?(c[V+4>>2]|0)!=(c[n+4>>2]|0):0){g=1;break}g=5}while(0);S=V+204|0;l=c[S>>2]|0;do if(l){if((f|0)==2?(c[V+4>>2]|0)!=(c[l+4>>2]|0):0)break;g=g|2}while(0);R=(g&2|0)==0;do if(R){c[Za>>2]=0;c[_a>>2]=0;c[$a>>2]=0;c[ia>>2]=0;m=0}else{if((c[V>>2]|0)>>>0<=5?(c[l>>2]|0)>>>0<=5:0){if((b[V+28>>1]|0)==0?(b[l+48>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[l+124>>2]|0)?(B=(b[V+132>>1]|0)-(b[l+172>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){h=(b[V+134>>1]|0)-(b[l+174>>1]|0)|0;h=(((h|0)>-1?h:0-h|0)|0)>3&1}else h=1;else h=2;c[ia>>2]=h;if((b[V+30>>1]|0)==0?(b[l+50>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[l+124>>2]|0)?(B=(b[V+136>>1]|0)-(b[l+176>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){j=(b[V+138>>1]|0)-(b[l+178>>1]|0)|0;j=(((j|0)>-1?j:0-j|0)|0)>3&1}else j=1;else j=2;c[$a>>2]=j;if((b[V+36>>1]|0)==0?(b[l+56>>1]|0)==0:0)if((c[V+120>>2]|0)==(c[l+128>>2]|0)?(B=(b[V+148>>1]|0)-(b[l+188>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){k=(b[V+150>>1]|0)-(b[l+190>>1]|0)|0;k=(((k|0)>-1?k:0-k|0)|0)>3&1}else k=1;else k=2;c[_a>>2]=k;if((b[V+38>>1]|0)==0?(b[l+58>>1]|0)==0:0)if((c[V+120>>2]|0)==(c[l+128>>2]|0)?(B=(b[V+152>>1]|0)-(b[l+192>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){f=(b[V+154>>1]|0)-(b[l+194>>1]|0)|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=1;else f=2;c[Za>>2]=f;m=(j|h|k|f|0)!=0&1;break}c[Za>>2]=4;c[_a>>2]=4;c[$a>>2]=4;c[ia>>2]=4;m=1}while(0);Q=(g&4|0)==0;do if(Q){c[la>>2]=0;c[ma>>2]=0;c[na>>2]=0;c[oa>>2]=0;k=c[V>>2]|0}else{k=c[V>>2]|0;if(k>>>0<=5?(c[n>>2]|0)>>>0<=5:0){if((b[V+28>>1]|0)==0?(b[n+38>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[n+120>>2]|0)?(B=(b[V+132>>1]|0)-(b[n+152>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){j=(b[V+134>>1]|0)-(b[n+154>>1]|0)|0;j=(((j|0)>-1?j:0-j|0)|0)>3&1}else j=1;else j=2;c[oa>>2]=j;if((b[V+32>>1]|0)==0?(b[n+42>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[n+120>>2]|0)?(B=(b[V+140>>1]|0)-(b[n+160>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){h=(b[V+142>>1]|0)-(b[n+162>>1]|0)|0;h=(((h|0)>-1?h:0-h|0)|0)>3&1}else h=1;else h=2;c[na>>2]=h;if((b[V+44>>1]|0)==0?(b[n+54>>1]|0)==0:0)if((c[V+124>>2]|0)==(c[n+128>>2]|0)?(B=(b[V+164>>1]|0)-(b[n+184>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){f=(b[V+166>>1]|0)-(b[n+186>>1]|0)|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=1;else f=2;c[ma>>2]=f;if((b[V+48>>1]|0)==0?(b[n+58>>1]|0)==0:0)if((c[V+124>>2]|0)==(c[n+128>>2]|0)?(B=(b[V+172>>1]|0)-(b[n+192>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){l=(b[V+174>>1]|0)-(b[n+194>>1]|0)|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=1;else l=2;c[la>>2]=l;if(m)break;m=(h|j|f|l|0)!=0&1;break}c[la>>2]=4;c[ma>>2]=4;c[na>>2]=4;c[oa>>2]=4;m=1}while(0);if(k>>>0<=5){do if((db(k)|0)!=1){f=c[V>>2]|0;if((f|0)==2){w=V+28|0;x=b[V+32>>1]|0;if(!(x<<16>>16))f=(b[w>>1]|0)!=0?2:0;else f=2;c[Ya>>2]=f;q=b[V+34>>1]|0;A=q<<16>>16==0;if(A)f=(b[V+30>>1]|0)!=0?2:0;else f=2;c[Xa>>2]=f;g=b[V+40>>1]|0;z=g<<16>>16==0;if(z)l=(b[V+36>>1]|0)!=0?2:0;else l=2;c[Wa>>2]=l;v=b[V+42>>1]|0;y=v<<16>>16==0;if(y)l=(b[V+38>>1]|0)!=0?2:0;else l=2;c[Va>>2]=l;h=b[V+48>>1]|0;if(!(h<<16>>16))l=(b[V+44>>1]|0)!=0?2:0;else l=2;c[Qa>>2]=l;k=b[V+50>>1]|0;B=k<<16>>16==0;if(B)l=(b[V+46>>1]|0)!=0?2:0;else l=2;c[Pa>>2]=l;p=b[V+56>>1]|0;f=p<<16>>16==0;if(f)n=(b[V+52>>1]|0)!=0?2:0;else n=2;c[Na>>2]=n;j=(b[V+58>>1]|0)==0;if(j)n=(b[V+54>>1]|0)!=0?2:0;else n=2;c[Ma>>2]=n;r=b[V+44>>1]|0;o=b[V+166>>1]|0;n=b[V+142>>1]|0;do if(!((r|x)<<16>>16)){u=(b[V+164>>1]|0)-(b[V+140>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){n=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){n=1;break}n=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else n=2;while(0);c[Ua>>2]=n;s=b[V+46>>1]|0;o=b[V+170>>1]|0;n=b[V+146>>1]|0;do if(!((s|q)<<16>>16)){u=(b[V+168>>1]|0)-(b[V+144>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[Ta>>2]=o;t=b[V+52>>1]|0;o=b[V+182>>1]|0;n=b[V+158>>1]|0;do if(!((t|g)<<16>>16)){u=(b[V+180>>1]|0)-(b[V+156>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Sa>>2]=o;u=b[V+54>>1]|0;o=b[V+186>>1]|0;n=b[V+162>>1]|0;do if(!((u|v)<<16>>16)){v=(b[V+184>>1]|0)-(b[V+160>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){o=1;break}v=o-n|0;if((((v|0)>-1?v:0-v|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Ra>>2]=o;l=b[V+30>>1]|0;if(!(l<<16>>16))o=(b[w>>1]|0)!=0?2:0;else o=2;c[Aa>>2]=o;n=b[V+36>>1]|0;if(!(n<<16>>16))o=l<<16>>16!=0?2:0;else o=2;c[za>>2]=o;if(!(b[V+38>>1]|0))o=n<<16>>16!=0?2:0;else o=2;c[ya>>2]=o;if(A)n=x<<16>>16!=0?2:0;else n=2;c[xa>>2]=n;if(z)l=q<<16>>16!=0?2:0;else l=2;c[wa>>2]=l;if(y)l=g<<16>>16!=0?2:0;else l=2;c[va>>2]=l;if(!(s<<16>>16))l=r<<16>>16!=0?2:0;else l=2;c[ua>>2]=l;if(!(t<<16>>16))l=s<<16>>16!=0?2:0;else l=2;c[ta>>2]=l;if(!(u<<16>>16))l=t<<16>>16!=0?2:0;else l=2;c[sa>>2]=l;if(B)h=h<<16>>16!=0?2:0;else h=2;c[ra>>2]=h;if(f)f=k<<16>>16!=0?2:0;else f=2;c[qa>>2]=f;if(j)f=p<<16>>16!=0?2:0;else f=2;c[pa>>2]=f;break}else if((f|0)==3){j=V+28|0;v=b[V+32>>1]|0;if(!(v<<16>>16))f=(b[j>>1]|0)!=0?2:0;else f=2;c[Ya>>2]=f;B=b[V+34>>1]|0;p=B<<16>>16==0;if(p)h=(b[V+30>>1]|0)!=0?2:0;else h=2;c[Xa>>2]=h;z=b[V+40>>1]|0;if(!(z<<16>>16))k=(b[V+36>>1]|0)!=0?2:0;else k=2;c[Wa>>2]=k;o=b[V+42>>1]|0;h=o<<16>>16==0;if(h)l=(b[V+38>>1]|0)!=0?2:0;else l=2;c[Va>>2]=l;f=b[V+44>>1]|0;if(!(f<<16>>16))l=v<<16>>16!=0?2:0;else l=2;c[Ua>>2]=l;A=b[V+46>>1]|0;g=A<<16>>16==0;if(g)l=B<<16>>16!=0?2:0;else l=2;c[Ta>>2]=l;y=b[V+52>>1]|0;if(!(y<<16>>16))l=z<<16>>16!=0?2:0;else l=2;c[Sa>>2]=l;k=b[V+54>>1]|0;q=k<<16>>16==0;if(q)l=o<<16>>16!=0?2:0;else l=2;c[Ra>>2]=l;r=b[V+48>>1]|0;if(!(r<<16>>16))n=f<<16>>16!=0?2:0;else n=2;c[Qa>>2]=n;x=b[V+50>>1]|0;s=x<<16>>16==0;if(s)n=A<<16>>16!=0?2:0;else n=2;c[Pa>>2]=n;w=b[V+56>>1]|0;if(!(w<<16>>16))o=y<<16>>16!=0?2:0;else o=2;c[Na>>2]=o;u=(b[V+58>>1]|0)==0;if(u)o=k<<16>>16!=0?2:0;else o=2;c[Ma>>2]=o;t=b[V+30>>1]|0;if(!(t<<16>>16))o=(b[j>>1]|0)!=0?2:0;else o=2;c[Aa>>2]=o;if(!(b[V+38>>1]|0))o=(b[V+36>>1]|0)!=0?2:0;else o=2;c[ya>>2]=o;if(p)n=v<<16>>16!=0?2:0;else n=2;c[xa>>2]=n;if(h)n=z<<16>>16!=0?2:0;else n=2;c[va>>2]=n;if(g)l=f<<16>>16!=0?2:0;else l=2;c[ua>>2]=l;if(q)l=y<<16>>16!=0?2:0;else l=2;c[sa>>2]=l;if(s)l=r<<16>>16!=0?2:0;else l=2;c[ra>>2]=l;if(u)l=w<<16>>16!=0?2:0;else l=2;c[pa>>2]=l;l=b[V+150>>1]|0;k=b[V+138>>1]|0;do if(!((b[V+36>>1]|t)<<16>>16)){v=(b[V+148>>1]|0)-(b[V+136>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){l=1;break}v=l-k|0;if((((v|0)>-1?v:0-v|0)|0)>3){l=1;break}l=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else l=2;while(0);c[za>>2]=l;l=b[V+158>>1]|0;k=b[V+146>>1]|0;do if(!((z|B)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+144>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}B=l-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}k=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else k=2;while(0);c[wa>>2]=k;l=b[V+182>>1]|0;k=b[V+170>>1]|0;do if(!((y|A)<<16>>16)){B=(b[V+180>>1]|0)-(b[V+168>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}B=l-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else f=2;while(0);c[ta>>2]=f;f=b[V+190>>1]|0;g=b[V+178>>1]|0;do if(!((w|x)<<16>>16)){B=(b[V+188>>1]|0)-(b[V+176>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}B=f-g|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else f=2;while(0);c[qa>>2]=f;break}else{K=b[V+32>>1]|0;z=b[V+28>>1]|0;P=b[V+142>>1]|0;q=b[V+134>>1]|0;if(!((z|K)<<16>>16)){B=(b[V+140>>1]|0)-(b[V+132>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)k=1;else{k=P-q|0;k=(((k|0)>-1?k:0-k|0)|0)>3&1}}else k=2;c[Ya>>2]=k;L=b[V+34>>1]|0;y=b[V+30>>1]|0;O=b[V+146>>1]|0;r=b[V+138>>1]|0;if(!((y|L)<<16>>16)){B=(b[V+144>>1]|0)-(b[V+136>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)l=1;else{l=O-r|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}}else l=2;c[Xa>>2]=l;M=b[V+40>>1]|0;x=b[V+36>>1]|0;N=b[V+158>>1]|0;s=b[V+150>>1]|0;if(!((x|M)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+148>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)n=1;else{n=N-s|0;n=(((n|0)>-1?n:0-n|0)|0)>3&1}}else n=2;c[Wa>>2]=n;n=b[V+42>>1]|0;B=b[V+38>>1]|0;J=b[V+162>>1]|0;A=b[V+154>>1]|0;if(!((B|n)<<16>>16)){w=(b[V+160>>1]|0)-(b[V+152>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3)o=1;else{o=J-A|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}}else o=2;c[Va>>2]=o;D=b[V+44>>1]|0;I=b[V+166>>1]|0;do if(!((D|K)<<16>>16)){w=(b[V+164>>1]|0)-(b[V+140>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3)o=1;else{w=I-P|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}}else o=2;while(0);c[Ua>>2]=o;E=b[V+46>>1]|0;H=b[V+170>>1]|0;do if(!((E|L)<<16>>16)){w=(b[V+168>>1]|0)-(b[V+144>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}w=H-O|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[Ta>>2]=o;F=b[V+52>>1]|0;G=b[V+182>>1]|0;do if(!((F|M)<<16>>16)){w=(b[V+180>>1]|0)-(b[V+156>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}w=G-N|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Sa>>2]=o;g=b[V+54>>1]|0;l=b[V+186>>1]|0;do if(!((g|n)<<16>>16)){w=(b[V+184>>1]|0)-(b[V+160>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}w=l-J|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else u=2;while(0);c[Ra>>2]=u;f=b[V+48>>1]|0;C=b[V+174>>1]|0;do if(!((f|D)<<16>>16)){w=(b[V+172>>1]|0)-(b[V+164>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=C-I|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Qa>>2]=u;h=b[V+50>>1]|0;k=b[V+178>>1]|0;do if(!((h|E)<<16>>16)){w=(b[V+176>>1]|0)-(b[V+168>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=k-H|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Pa>>2]=u;j=b[V+56>>1]|0;p=b[V+190>>1]|0;do if(!((j|F)<<16>>16)){w=(b[V+188>>1]|0)-(b[V+180>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=p-G|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Na>>2]=u;w=b[V+58>>1]|0;t=b[V+194>>1]|0;do if(!((w|g)<<16>>16)){v=(b[V+192>>1]|0)-(b[V+184>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){v=1;break}v=t-l|0;v=(((v|0)>-1?v:0-v|0)|0)>3&1}else v=2;while(0);c[Ma>>2]=v;do if(!((y|z)<<16>>16)){z=(b[V+136>>1]|0)-(b[V+132>>1]|0)|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}u=r-q|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Aa>>2]=u;do if(!((x|y)<<16>>16)){z=(b[V+148>>1]|0)-(b[V+136>>1]|0)|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}z=s-r|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}u=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else u=2;while(0);c[za>>2]=u;do if(!((B|x)<<16>>16)){B=(b[V+152>>1]|0)-(b[V+148>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){u=1;break}u=A-s|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[ya>>2]=u;do if(!((L|K)<<16>>16)){B=(b[V+144>>1]|0)-(b[V+140>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=O-P|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}else o=2;while(0);c[xa>>2]=o;do if(!((M|L)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+144>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}B=N-O|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[wa>>2]=o;do if(!((n|M)<<16>>16)){B=(b[V+160>>1]|0)-(b[V+156>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=J-N|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}else o=2;while(0);c[va>>2]=o;do if(!((E|D)<<16>>16)){B=(b[V+168>>1]|0)-(b[V+164>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}n=H-I|0;n=(((n|0)>-1?n:0-n|0)|0)>3&1}else n=2;while(0);c[ua>>2]=n;do if(!((F|E)<<16>>16)){B=(b[V+180>>1]|0)-(b[V+168>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}B=G-H|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}n=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else n=2;while(0);c[ta>>2]=n;do if(!((g|F)<<16>>16)){B=(b[V+184>>1]|0)-(b[V+180>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){l=1;break}l=l-G|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=2;while(0);c[sa>>2]=l;do if(!((h|f)<<16>>16)){B=(b[V+176>>1]|0)-(b[V+172>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){l=1;break}l=k-C|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=2;while(0);c[ra>>2]=l;do if(!((j|h)<<16>>16)){B=(b[V+188>>1]|0)-(b[V+176>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}B=p-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}k=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else k=2;while(0);c[qa>>2]=k;do if(!((w|j)<<16>>16)){B=(b[V+192>>1]|0)-(b[V+188>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=t-p|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=2;while(0);c[pa>>2]=f;break}}else vc(V,ia);while(0);if(!(m|c[Ya>>2]|c[Xa>>2]|c[Wa>>2]|c[Va>>2]|c[Ua>>2]|c[Ta>>2]|c[Sa>>2]|c[Ra>>2]|c[Qa>>2]|c[Pa>>2]|c[Na>>2]|c[Ma>>2]|c[Aa>>2]|c[za>>2]|c[ya>>2]|c[xa>>2]|c[wa>>2]|c[va>>2]|c[ua>>2]|c[ta>>2]|c[sa>>2]|c[ra>>2]|c[qa>>2]|c[pa>>2]))break}else{c[Ma>>2]=3;c[Na>>2]=3;c[Pa>>2]=3;c[Qa>>2]=3;c[Ra>>2]=3;c[Sa>>2]=3;c[Ta>>2]=3;c[Ua>>2]=3;c[Va>>2]=3;c[Wa>>2]=3;c[Xa>>2]=3;c[Ya>>2]=3;c[pa>>2]=3;c[qa>>2]=3;c[ra>>2]=3;c[sa>>2]=3;c[ta>>2]=3;c[ua>>2]=3;c[va>>2]=3;c[wa>>2]=3;c[xa>>2]=3;c[ya>>2]=3;c[za>>2]=3;c[Aa>>2]=3}J=V+20|0;g=c[J>>2]|0;L=V+12|0;k=Oa(0,51,(c[L>>2]|0)+g|0)|0;K=V+16|0;h=Oa(0,51,(c[K>>2]|0)+g|0)|0;j=d[6864+k>>0]|0;c[ha>>2]=j;h=d[6920+h>>0]|0;c[ja>>2]=h;k=6976+(k*3|0)|0;c[Ka>>2]=k;do if(!R){l=c[(c[S>>2]|0)+20>>2]|0;if((l|0)==(g|0)){c[X>>2]=j;c[_>>2]=h;c[La>>2]=k;break}else{A=(g+1+l|0)>>>1;B=Oa(0,51,(c[L>>2]|0)+A|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[X>>2]=d[6864+B>>0];c[_>>2]=d[6920+A>>0];c[La>>2]=6976+(B*3|0);break}}while(0);do if(!Q){f=c[(c[T>>2]|0)+20>>2]|0;if((f|0)==(g|0)){c[Y>>2]=c[ha>>2];c[$>>2]=c[ja>>2];c[da>>2]=c[Ka>>2];break}else{A=(g+1+f|0)>>>1;B=Oa(0,51,(c[L>>2]|0)+A|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[Y>>2]=d[6864+B>>0];c[$>>2]=d[6920+A>>0];c[da>>2]=6976+(B*3|0);break}}while(0);M=Z(aa,ea)|0;P=3;o=0;O=(c[e>>2]|0)+((M<<8)+(U<<4))|0;N=ia;while(1){l=c[N+4>>2]|0;if(l)wc(O,l,fa,Da);l=c[N+12>>2]|0;if(l)wc(O+4|0,l,ga,Da);k=N+16|0;m=c[N+20>>2]|0;if(m)wc(O+8|0,m,ga,Da);j=N+24|0;m=c[N+28>>2]|0;if(m)wc(O+12|0,m,ga,Da);n=c[N>>2]|0;l=N+8|0;m=c[l>>2]|0;a:do if(((n|0)==(m|0)?(n|0)==(c[k>>2]|0):0)?(n|0)==(c[j>>2]|0):0){if(!n)break;y=c[La+(o*12|0)+4>>2]|0;x=c[La+(o*12|0)+8>>2]|0;if(n>>>0<4){t=d[(c[La+(o*12|0)>>2]|0)+(n+-1)>>0]|0;k=0-t|0;j=t+1|0;f=O;h=16;while(1){o=f+Ca|0;s=d[o>>0]|0;u=f+Ja|0;r=d[u>>0]|0;q=d[f>>0]|0;m=f+Da|0;g=d[m>>0]|0;B=r-q|0;do if(((B|0)>-1?B:0-B|0)>>>0>>0){B=s-r|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=g-q|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;n=d[f+Ha>>0]|0;B=n-r|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[o>>0]=(Oa(k,t,((r+1+q|0)>>>1)-(s<<1)+n>>1)|0)+s;o=j}else o=t;n=d[f+Ia>>0]|0;B=n-q|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[m>>0]=(Oa(k,t,((r+1+q|0)>>>1)-(g<<1)+n>>1)|0)+g;o=o+1|0}A=Oa(0-o|0,o,s+4-g+(q-r<<2)>>3)|0;B=a[3472+((q|512)-A)>>0]|0;a[u>>0]=a[3472+(A+(r|512))>>0]|0;a[f>>0]=B}while(0);h=h+-1|0;if(!h)break a;else f=f+1|0}}n=(y>>>2)+2|0;t=O;u=16;while(1){m=t+Ca|0;f=d[m>>0]|0;l=t+Ja|0;g=d[l>>0]|0;p=d[t>>0]|0;k=t+Da|0;q=d[k>>0]|0;o=g-p|0;o=(o|0)>-1?o:0-o|0;b:do if(o>>>0>>0){B=f-g|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=q-p|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;j=t+Ha|0;r=d[j>>0]|0;h=t+Ia|0;s=d[h>>0]|0;do if(o>>>0>>0){B=r-g|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){B=g+f+p|0;a[l>>0]=(q+4+(B<<1)+r|0)>>>3;a[m>>0]=(B+2+r|0)>>>2;a[j>>0]=(B+4+(r*3|0)+(d[t+Ea>>0]<<1)|0)>>>3}else a[l>>0]=(g+2+(f<<1)+q|0)>>>2;B=s-p|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=p+g+q|0;a[t>>0]=(f+4+(B<<1)+s|0)>>>3;a[k>>0]=(B+2+s|0)>>>2;a[h>>0]=(B+4+(s*3|0)+(d[t+Ga>>0]<<1)|0)>>>3;break b}else a[l>>0]=(g+2+(f<<1)+q|0)>>>2;while(0);a[t>>0]=(f+2+p+(q<<1)|0)>>>2}while(0);u=u+-1|0;if(!u)break;else t=t+1|0}}else ab=311;while(0);do if((ab|0)==311){ab=0;if(n){xc(O,n,La+(o*12|0)|0,Da);m=c[l>>2]|0}if(m)xc(O+4|0,m,La+(o*12|0)|0,Da);m=c[k>>2]|0;if(m)xc(O+8|0,m,La+(o*12|0)|0,Da);l=c[j>>2]|0;if(!l)break;xc(O+12|0,l,La+(o*12|0)|0,Da)}while(0);if(!P)break;else{P=P+-1|0;o=2;O=O+Ba|0;N=N+32|0}}h=c[V+24>>2]|0;g=c[192+((Oa(0,51,(c[J>>2]|0)+h|0)|0)<<2)>>2]|0;m=Oa(0,51,(c[L>>2]|0)+g|0)|0;j=Oa(0,51,(c[K>>2]|0)+g|0)|0;k=d[6864+m>>0]|0;c[ha>>2]=k;j=d[6920+j>>0]|0;c[ja>>2]=j;m=6976+(m*3|0)|0;c[Ka>>2]=m;do if(!R){l=c[(c[S>>2]|0)+20>>2]|0;if((l|0)==(c[J>>2]|0)){c[X>>2]=k;c[_>>2]=j;c[La>>2]=m;break}else{A=(g+1+(c[192+((Oa(0,51,l+h|0)|0)<<2)>>2]|0)|0)>>>1;B=Oa(0,51,A+(c[L>>2]|0)|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[X>>2]=d[6864+B>>0];c[_>>2]=d[6920+A>>0];c[La>>2]=6976+(B*3|0);break}}while(0);do if(!Q){f=c[(c[T>>2]|0)+20>>2]|0;if((f|0)==(c[J>>2]|0)){c[Y>>2]=c[ha>>2];c[$>>2]=c[ja>>2];c[da>>2]=c[Ka>>2];break}else{A=(g+1+(c[192+((Oa(0,51,f+h|0)|0)<<2)>>2]|0)|0)>>>1;B=Oa(0,51,A+(c[L>>2]|0)|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[Y>>2]=d[6864+B>>0];c[$>>2]=d[6920+A>>0];c[da>>2]=6976+(B*3|0);break}}while(0);j=c[e>>2]|0;l=(U<<3)+Fa+(M<<6)|0;n=j+l|0;l=j+(l+ba)|0;j=0;h=ia;o=0;while(1){g=h+4|0;f=c[g>>2]|0;if(f){yc(n,f,fa,ca);yc(l,c[g>>2]|0,fa,ca)}g=h+36|0;f=c[g>>2]|0;if(f){yc(n+Da|0,f,fa,ca);yc(l+Da|0,c[g>>2]|0,fa,ca)}m=h+16|0;g=h+20|0;f=c[g>>2]|0;if(f){yc(n+4|0,f,ga,ca);yc(l+4|0,c[g>>2]|0,ga,ca)}g=h+52|0;f=c[g>>2]|0;if(f){yc(n+W|0,f,ga,ca);yc(l+W|0,c[g>>2]|0,ga,ca)}g=c[h>>2]|0;k=h+8|0;f=c[k>>2]|0;do if((g|0)==(f|0)){if((g|0)!=(c[m>>2]|0)){ab=342;break}if((g|0)!=(c[h+24>>2]|0)){ab=342;break}if(!g)break;B=La+(j*12|0)|0;zc(n,g,B,ca);zc(l,c[h>>2]|0,B,ca)}else ab=342;while(0);do if((ab|0)==342){ab=0;if(g){f=La+(j*12|0)|0;Ac(n,g,f,ca);Ac(l,c[h>>2]|0,f,ca);f=c[k>>2]|0}if(f){B=La+(j*12|0)|0;Ac(n+2|0,f,B,ca);Ac(l+2|0,c[k>>2]|0,B,ca)}f=c[m>>2]|0;if(f){B=La+(j*12|0)|0;Ac(n+4|0,f,B,ca);Ac(l+4|0,c[m>>2]|0,B,ca)}g=h+24|0;f=c[g>>2]|0;if(!f)break;B=La+(j*12|0)|0;Ac(n+6|0,f,B,ca);Ac(l+6|0,c[g>>2]|0,B,ca)}while(0);o=o+1|0;if((o|0)==2)break;else{n=n+Ia|0;l=l+Ia|0;j=2;h=h+64|0}}}while(0);f=U+1|0;g=(f|0)==(ea|0);aa=(g&1)+aa|0;if(aa>>>0>=(c[ka>>2]|0)>>>0)break;else{U=g?0:f;V=V+216|0}}i=bb;return}function vc(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;B=i;l=a+28|0;y=b[a+32>>1]|0;if(!(y<<16>>16))e=(b[l>>1]|0)!=0?2:0;else e=2;c[d+32>>2]=e;z=b[a+34>>1]|0;x=z<<16>>16==0;if(x)e=(b[a+30>>1]|0)!=0?2:0;else e=2;c[d+40>>2]=e;A=b[a+40>>1]|0;v=A<<16>>16==0;if(v)e=(b[a+36>>1]|0)!=0?2:0;else e=2;c[d+48>>2]=e;f=b[a+42>>1]|0;w=f<<16>>16==0;if(w)e=(b[a+38>>1]|0)!=0?2:0;else e=2;c[d+56>>2]=e;s=b[a+44>>1]|0;if(!(s<<16>>16))e=y<<16>>16!=0?2:0;else e=2;c[d+64>>2]=e;t=b[a+46>>1]|0;p=t<<16>>16==0;if(p)e=z<<16>>16!=0?2:0;else e=2;c[d+72>>2]=e;u=b[a+52>>1]|0;q=u<<16>>16==0;if(q)e=A<<16>>16!=0?2:0;else e=2;c[d+80>>2]=e;g=b[a+54>>1]|0;r=g<<16>>16==0;if(r)e=f<<16>>16!=0?2:0;else e=2;c[d+88>>2]=e;m=b[a+48>>1]|0;if(!(m<<16>>16))e=s<<16>>16!=0?2:0;else e=2;c[d+96>>2]=e;n=b[a+50>>1]|0;h=n<<16>>16==0;if(h)e=t<<16>>16!=0?2:0;else e=2;c[d+104>>2]=e;o=b[a+56>>1]|0;j=o<<16>>16==0;if(j)f=u<<16>>16!=0?2:0;else f=2;c[d+112>>2]=f;k=(b[a+58>>1]|0)==0;if(k)f=g<<16>>16!=0?2:0;else f=2;c[d+120>>2]=f;g=b[a+30>>1]|0;if(!(g<<16>>16))f=(b[l>>1]|0)!=0?2:0;else f=2;c[d+12>>2]=f;e=b[a+36>>1]|0;if(!(e<<16>>16))f=g<<16>>16!=0?2:0;else f=2;c[d+20>>2]=f;if(!(b[a+38>>1]|0))e=e<<16>>16!=0?2:0;else e=2;c[d+28>>2]=e;if(x)e=y<<16>>16!=0?2:0;else e=2;c[d+44>>2]=e;if(v)e=z<<16>>16!=0?2:0;else e=2;c[d+52>>2]=e;if(w)e=A<<16>>16!=0?2:0;else e=2;c[d+60>>2]=e;if(p)e=s<<16>>16!=0?2:0;else e=2;c[d+76>>2]=e;if(q)e=t<<16>>16!=0?2:0;else e=2;c[d+84>>2]=e;if(r)e=u<<16>>16!=0?2:0;else e=2;c[d+92>>2]=e;if(h)e=m<<16>>16!=0?2:0;else e=2;c[d+108>>2]=e;if(j)e=n<<16>>16!=0?2:0;else e=2;c[d+116>>2]=e;if(!k){y=2;z=d+124|0;c[z>>2]=y;i=B;return}y=o<<16>>16!=0?2:0;z=d+124|0;c[z>>2]=y;i=B;return}function wc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=i;u=c[f+4>>2]|0;v=c[f+8>>2]|0;if(e>>>0<4){l=d[(c[f>>2]|0)+(e+-1)>>0]|0;n=0-l|0;m=l+1|0;k=4;while(1){f=b+-2|0;s=d[f>>0]|0;t=b+-1|0;r=d[t>>0]|0;q=d[b>>0]|0;j=b+1|0;h=d[j>>0]|0;o=r-q|0;if((((o|0)>-1?o:0-o|0)>>>0>>0?(o=s-r|0,((o|0)>-1?o:0-o|0)>>>0>>0):0)?(o=h-q|0,((o|0)>-1?o:0-o|0)>>>0>>0):0){e=d[b+-3>>0]|0;p=d[b+2>>0]|0;o=e-r|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){a[f>>0]=(Oa(n,l,((r+1+q|0)>>>1)-(s<<1)+e>>1)|0)+s;f=m}else f=l;o=p-q|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){a[j>>0]=(Oa(n,l,((r+1+q|0)>>>1)-(h<<1)+p>>1)|0)+h;f=f+1|0}j=Oa(0-f|0,f,s+4-h+(q-r<<2)>>3)|0;o=a[3472+((q|512)-j)>>0]|0;a[t>>0]=a[3472+((r|512)+j)>>0]|0;a[b>>0]=o}k=k+-1|0;if(!k)break;else b=b+g|0}i=w;return}t=(u>>>2)+2|0;s=4;while(1){k=b+-2|0;q=d[k>>0]|0;l=b+-1|0;r=d[l>>0]|0;m=d[b>>0]|0;e=b+1|0;n=d[e>>0]|0;f=r-m|0;f=(f|0)>-1?f:0-f|0;do if((f>>>0>>0?(o=q-r|0,((o|0)>-1?o:0-o|0)>>>0>>0):0)?(o=n-m|0,((o|0)>-1?o:0-o|0)>>>0>>0):0){h=b+-3|0;o=d[h>>0]|0;j=b+2|0;p=d[j>>0]|0;if(f>>>0>>0){f=o-r|0;if(((f|0)>-1?f:0-f|0)>>>0>>0){f=r+q+m|0;a[l>>0]=(n+4+(f<<1)+o|0)>>>3;a[k>>0]=(f+2+o|0)>>>2;a[h>>0]=(f+4+(o*3|0)+((d[b+-4>>0]|0)<<1)|0)>>>3}else a[l>>0]=(r+2+(q<<1)+n|0)>>>2;o=p-m|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){o=m+r+n|0;a[b>>0]=(q+4+(o<<1)+p|0)>>>3;a[e>>0]=(o+2+p|0)>>>2;a[j>>0]=(o+4+(p*3|0)+((d[b+3>>0]|0)<<1)|0)>>>3;break}}else a[l>>0]=(r+2+(q<<1)+n|0)>>>2;a[b>>0]=(q+2+m+(n<<1)|0)>>>2}while(0);s=s+-1|0;if(!s)break;else b=b+g|0}i=w;return}function xc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;A=i;u=d[(c[f>>2]|0)+(e+-1)>>0]|0;w=0-g|0;v=w<<1;t=f+4|0;o=f+8|0;q=Z(g,-3)|0;s=0-u|0;p=u+1|0;r=g<<1;n=4;while(1){e=b+v|0;k=b+w|0;j=b+g|0;f=a[j>>0]|0;l=d[k>>0]|0;m=d[b>>0]|0;h=l-m|0;if((((h|0)>-1?h:0-h|0)>>>0<(c[t>>2]|0)>>>0?(y=d[e>>0]|0,h=y-l|0,x=c[o>>2]|0,((h|0)>-1?h:0-h|0)>>>0>>0):0)?(z=f&255,f=z-m|0,((f|0)>-1?f:0-f|0)>>>0>>0):0){f=d[b+q>>0]|0;h=f-l|0;if(((h|0)>-1?h:0-h|0)>>>0>>0){a[e>>0]=(Oa(s,u,((l+1+m|0)>>>1)-(y<<1)+f>>1)|0)+y;e=c[o>>2]|0;f=p}else{e=x;f=u}h=d[b+r>>0]|0;B=h-m|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[j>>0]=(Oa(s,u,((l+1+m|0)>>>1)-(z<<1)+h>>1)|0)+z;f=f+1|0}f=Oa(0-f|0,f,4-z+(m-l<<2)+y>>3)|0;e=a[3472+((m|512)-f)>>0]|0;a[k>>0]=a[3472+((l|512)+f)>>0]|0;a[b>>0]=e}n=n+-1|0;if(!n)break;else b=b+1|0}i=A;return} +function ya(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+15&-16;return b|0}function za(){return i|0}function Aa(a){a=a|0;i=a}function Ba(a,b){a=a|0;b=b|0;if(!m){m=a;n=b}}function Ca(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Da(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Ea(a){a=a|0;B=a}function Fa(){return B|0}function Ga(a,b,e,f){a=a|0;b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;k=i;g=d[8+b>>0]|0;j=d[64+b>>0]|0;b=c[120+(j*12|0)>>2]<>2]<>2]<>2]=Z(c[a>>2]|0,b)|0;a:do if(!(f&65436)){if(f&98){n=a+4|0;l=Z(c[n>>2]|0,h)|0;j=a+20|0;m=Z(c[j>>2]|0,b)|0;e=a+24|0;g=Z(c[e>>2]|0,h)|0;h=c[a>>2]|0;b=(l>>1)-g|0;g=l+(g>>1)|0;l=m+h+32|0;f=l+g>>6;c[a>>2]=f;m=h-m+32|0;h=m+b>>6;c[n>>2]=h;b=m-b>>6;c[a+8>>2]=b;g=l-g>>6;c[a+12>>2]=g;c[a+48>>2]=f;c[a+32>>2]=f;c[a+16>>2]=f;c[a+52>>2]=h;c[a+36>>2]=h;c[j>>2]=h;c[a+56>>2]=b;c[a+40>>2]=b;c[e>>2]=b;c[a+60>>2]=g;c[a+44>>2]=g;c[a+28>>2]=g;if((f+512|0)>>>0>1023|(h+512|0)>>>0>1023|(b+512|0)>>>0>1023|(g+512|0)>>>0>1023)g=1;else break;i=k;return g|0}g=(c[a>>2]|0)+32>>6;if((g+512|0)>>>0>1023){m=1;i=k;return m|0}else{c[a+60>>2]=g;c[a+56>>2]=g;c[a+52>>2]=g;c[a+48>>2]=g;c[a+44>>2]=g;c[a+40>>2]=g;c[a+36>>2]=g;c[a+32>>2]=g;c[a+28>>2]=g;c[a+24>>2]=g;c[a+20>>2]=g;c[a+16>>2]=g;c[a+12>>2]=g;c[a+8>>2]=g;c[a+4>>2]=g;c[a>>2]=g;break}}else{z=a+4|0;s=a+56|0;w=a+60|0;t=c[w>>2]|0;u=Z(c[z>>2]|0,h)|0;c[s>>2]=Z(c[s>>2]|0,h)|0;c[w>>2]=Z(t,g)|0;w=a+8|0;t=c[w>>2]|0;s=a+16|0;y=Z(c[a+20>>2]|0,b)|0;o=Z(c[s>>2]|0,g)|0;q=a+12|0;p=c[q>>2]|0;f=Z(c[a+32>>2]|0,h)|0;e=Z(c[a+24>>2]|0,h)|0;r=c[a+28>>2]|0;j=Z(c[a+48>>2]|0,g)|0;n=Z(c[a+36>>2]|0,h)|0;l=c[a+44>>2]|0;m=Z(c[a+40>>2]|0,g)|0;g=Z(c[a+52>>2]|0,h)|0;x=c[a>>2]|0;v=y+x|0;y=x-y|0;x=(u>>1)-e|0;u=(e>>1)+u|0;e=u+v|0;c[a>>2]=e;c[z>>2]=x+y;c[w>>2]=y-x;c[q>>2]=v-u;q=Z(h,r+t|0)|0;r=Z(t-r|0,h)|0;h=(o>>1)-j|0;o=(j>>1)+o|0;j=o+q|0;c[s>>2]=j;c[a+20>>2]=h+r;c[a+24>>2]=r-h;c[a+28>>2]=q-o;o=Z(b,l+p|0)|0;b=Z(p-l|0,b)|0;l=(f>>1)-g|0;f=(g>>1)+f|0;h=f+o|0;c[a+32>>2]=h;c[a+36>>2]=l+b;c[a+40>>2]=b-l;c[a+44>>2]=o-f;f=a+56|0;o=c[f>>2]|0;l=o+n|0;o=n-o|0;b=a+60|0;g=c[b>>2]|0;n=(m>>1)-g|0;m=(g>>1)+m|0;g=m+l|0;c[a+48>>2]=g;c[a+52>>2]=n+o;c[f>>2]=o-n;c[b>>2]=l-m;b=j;j=3;while(1){v=(b>>1)-g|0;g=(g>>1)+b|0;w=h+e+32|0;x=w+g>>6;c[a>>2]=x;b=e-h+32|0;y=b+v>>6;c[a+16>>2]=y;b=b-v>>6;c[a+32>>2]=b;g=w-g>>6;c[a+48>>2]=g;if((x+512|0)>>>0>1023|(y+512|0)>>>0>1023){g=1;b=14;break}if((b+512|0)>>>0>1023|(g+512|0)>>>0>1023){g=1;b=14;break}f=a+4|0;if(!j)break a;e=c[f>>2]|0;h=c[a+36>>2]|0;b=c[a+20>>2]|0;g=c[a+52>>2]|0;a=f;j=j+-1|0}if((b|0)==14){i=k;return g|0}}while(0);y=0;i=k;return y|0}function Ha(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;B=i;e=a[64+d>>0]|0;s=a[8+d>>0]|0;D=b+8|0;u=c[D>>2]|0;j=c[b+20>>2]|0;q=b+16|0;y=c[q>>2]|0;r=b+32|0;z=c[r>>2]|0;E=b+12|0;v=c[E>>2]|0;f=c[b+24>>2]|0;m=c[b+28>>2]|0;o=b+48|0;g=c[o>>2]|0;C=c[b+36>>2]|0;A=c[b+40>>2]|0;F=c[b+44>>2]|0;h=c[b+52>>2]|0;p=c[b>>2]|0;l=j+p|0;j=p-j|0;p=b+4|0;x=c[p>>2]|0;t=x-f|0;x=f+x|0;f=x+l|0;c[b>>2]=f;k=t+j|0;c[p>>2]=k;t=j-t|0;c[D>>2]=t;x=l-x|0;c[E>>2]=x;E=m+u|0;m=u-m|0;u=y-g|0;y=g+y|0;g=y+E|0;c[q>>2]=g;l=u+m|0;c[b+20>>2]=l;u=m-u|0;c[b+24>>2]=u;y=E-y|0;c[b+28>>2]=y;E=F+v|0;F=v-F|0;v=z-h|0;z=h+z|0;h=z+E|0;c[b+32>>2]=h;m=v+F|0;c[b+36>>2]=m;v=F-v|0;c[b+40>>2]=v;z=E-z|0;c[b+44>>2]=z;E=b+56|0;F=c[E>>2]|0;D=F+C|0;F=C-F|0;C=b+60|0;j=c[C>>2]|0;w=A-j|0;A=j+A|0;j=A+D|0;c[b+48>>2]=j;n=w+F|0;c[b+52>>2]=n;w=F-w|0;c[E>>2]=w;A=D-A|0;c[C>>2]=A;s=s&255;e=c[120+((e&255)*12|0)>>2]|0;if(d>>>0>11){d=e<>2]=Z(e+s|0,d)|0;c[q>>2]=Z(f+h|0,d)|0;c[r>>2]=Z(h-f|0,d)|0;c[o>>2]=Z(s-e|0,d)|0;r=m+k|0;e=k-m|0;q=l-n|0;s=n+l|0;c[p>>2]=Z(s+r|0,d)|0;c[b+20>>2]=Z(q+e|0,d)|0;c[b+36>>2]=Z(e-q|0,d)|0;c[b+52>>2]=Z(r-s|0,d)|0;s=v+t|0;t=t-v|0;v=u-w|0;w=w+u|0;c[b+8>>2]=Z(w+s|0,d)|0;c[b+24>>2]=Z(v+t|0,d)|0;c[b+40>>2]=Z(t-v|0,d)|0;c[b+56>>2]=Z(s-w|0,d)|0;w=z+x|0;v=x-z|0;x=y-A|0;y=A+y|0;c[b+12>>2]=Z(y+w|0,d)|0;c[b+28>>2]=Z(x+v|0,d)|0;c[b+44>>2]=Z(v-x|0,d)|0;c[b+60>>2]=Z(w-y|0,d)|0;i=B;return}else{C=(d+-6|0)>>>0<6?1:2;d=2-s|0;s=h+f|0;D=f-h|0;h=g-j|0;f=j+g|0;c[b>>2]=(Z(f+s|0,e)|0)+C>>d;c[q>>2]=(Z(h+D|0,e)|0)+C>>d;c[r>>2]=(Z(D-h|0,e)|0)+C>>d;c[o>>2]=(Z(s-f|0,e)|0)+C>>d;r=m+k|0;f=k-m|0;q=l-n|0;s=n+l|0;c[p>>2]=(Z(s+r|0,e)|0)+C>>d;c[b+20>>2]=(Z(q+f|0,e)|0)+C>>d;c[b+36>>2]=(Z(f-q|0,e)|0)+C>>d;c[b+52>>2]=(Z(r-s|0,e)|0)+C>>d;s=v+t|0;t=t-v|0;v=u-w|0;w=w+u|0;c[b+8>>2]=(Z(w+s|0,e)|0)+C>>d;c[b+24>>2]=(Z(v+t|0,e)|0)+C>>d;c[b+40>>2]=(Z(t-v|0,e)|0)+C>>d;c[b+56>>2]=(Z(s-w|0,e)|0)+C>>d;w=z+x|0;v=x-z|0;x=y-A|0;y=A+y|0;c[b+12>>2]=(Z(y+w|0,e)|0)+C>>d;c[b+28>>2]=(Z(x+v|0,e)|0)+C>>d;c[b+44>>2]=(Z(v-x|0,e)|0)+C>>d;c[b+60>>2]=(Z(w-y|0,e)|0)+C>>d;i=B;return}}function Ia(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;e=c[120+((d[64+b>>0]|0)*12|0)>>2]|0;if(b>>>0>5){e=e<<(d[8+b>>0]|0)+-1;b=0}else b=1;k=c[a>>2]|0;g=a+8|0;h=c[g>>2]|0;m=h+k|0;h=k-h|0;k=a+4|0;j=c[k>>2]|0;l=a+12|0;f=c[l>>2]|0;i=j-f|0;j=f+j|0;c[a>>2]=(Z(j+m|0,e)|0)>>b;c[k>>2]=(Z(m-j|0,e)|0)>>b;c[g>>2]=(Z(i+h|0,e)|0)>>b;c[l>>2]=(Z(h-i|0,e)|0)>>b;l=a+16|0;i=c[l>>2]|0;h=a+24|0;g=c[h>>2]|0;k=g+i|0;g=i-g|0;i=a+20|0;j=c[i>>2]|0;a=a+28|0;m=c[a>>2]|0;f=j-m|0;j=m+j|0;c[l>>2]=(Z(j+k|0,e)|0)>>b;c[i>>2]=(Z(k-j|0,e)|0)>>b;c[h>>2]=(Z(f+g|0,e)|0)>>b;c[a>>2]=(Z(g-f|0,e)|0)>>b;return}function Ja(a,b){a=a|0;b=b|0;var c=0,d=0;d=i;b=1<>>1}while((c|0)!=0&(c&a|0)==0);i=d;return b|0}function Ka(a){a=a|0;var b=0,d=0;d=i;b=8-(c[a+8>>2]|0)|0;a=jb(a,b)|0;if((a|0)==-1){a=1;i=d;return a|0}a=(a|0)!=(c[400+(b+-1<<2)>>2]|0)&1;i=d;return a|0}function La(a){a=a|0;var b=0,d=0,e=0,f=0;d=i;f=c[a+12>>2]<<3;e=c[a+16>>2]|0;b=f-e|0;if((f|0)==(e|0)){a=0;i=d;return a|0}if(b>>>0>8){a=1;i=d;return a|0}else{a=((kb(a)|0)>>>(32-b|0)|0)!=(1<>2]|0;do{d=d+1|0;if(d>>>0>=b>>>0)break}while((c[a+(d<<2)>>2]|0)!=(e|0));i=f;return ((d|0)==(b|0)?0:d)|0}function Na(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=c[a+4>>2]|0;f=(b>>>0)%(e>>>0)|0;d=b-f|0;b=Z(c[a+8>>2]|0,e)|0;e=c[a>>2]|0;c[a+12>>2]=e+((d<<8)+(f<<4));d=(f<<3)+(b<<8)+(d<<6)|0;c[a+16>>2]=e+d;c[a+20>>2]=e+(d+(b<<6));return}function Oa(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)>=(a|0))a=(c|0)>(b|0)?b:c;return a|0}function Pa(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=i;a:do if(((e>>>0>3?(a[b>>0]|0)==0:0)?(a[b+1>>0]|0)==0:0)?(h=a[b+2>>0]|0,(h&255)<2):0){b:do if((e|0)!=3){p=-3;q=3;k=b+3|0;j=2;while(1){if(h<<24>>24)if(h<<24>>24==1&j>>>0>1){o=q;h=0;m=0;l=0;break}else j=0;else j=j+1|0;l=q+1|0;if((l|0)==(e|0))break b;h=a[k>>0]|0;p=~q;q=l;k=k+1|0}while(1){r=a[k>>0]|0;n=o+1|0;j=r<<24>>24!=0;l=(j&1^1)+l|0;h=r<<24>>24==3&(l|0)==2?1:h;if(r<<24>>24==1&l>>>0>1){r=14;break}if(j){m=l>>>0>2?1:m;l=0}if((n|0)==(e|0)){r=18;break}else{o=n;k=k+1|0}}if((r|0)==14){n=p+o-l|0;c[f+12>>2]=n;j=q;l=l-(l>>>0<3?l:3)|0;break a}else if((r|0)==18){n=p+e-l|0;c[f+12>>2]=n;j=q;break a}}while(0);c[g>>2]=e;q=1;i=s;return q|0}else r=19;while(0);if((r|0)==19){c[f+12>>2]=e;n=e;h=1;j=0;m=0;l=0}k=b+j|0;c[f>>2]=k;c[f+4>>2]=k;c[f+8>>2]=0;c[f+16>>2]=0;o=f+12|0;c[g>>2]=l+j+n;if(m){q=1;i=s;return q|0}if(!h){q=0;i=s;return q|0}l=c[o>>2]|0;h=k;m=k;j=0;c:while(1){while(1){q=l;l=l+-1|0;if(!q){r=31;break c}k=a[h>>0]|0;if((j|0)!=2)break;if(k<<24>>24!=3){r=29;break}if(!l){h=1;r=32;break c}h=h+1|0;if((d[h>>0]|0)>3){h=1;r=32;break c}else j=0}if((r|0)==29){r=0;if((k&255)<3){h=1;r=32;break}else j=2}a[m>>0]=k;h=h+1|0;m=m+1|0;j=k<<24>>24==0?j+1|0:0}if((r|0)==31){c[o>>2]=m-h+(c[o>>2]|0);q=0;i=s;return q|0}else if((r|0)==32){i=s;return h|0}return 0}function Qa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;i=i+16|0;n=o;id(b,0,92);f=jb(a,8)|0;a:do if((((f|0)!=-1?(c[b>>2]=f,jb(a,1)|0,jb(a,1)|0,(jb(a,1)|0)!=-1):0)?(jb(a,5)|0)!=-1:0)?(e=jb(a,8)|0,(e|0)!=-1):0){m=b+4|0;c[m>>2]=e;f=b+8|0;d=nb(a,f)|0;if(!d)if((c[f>>2]|0)>>>0<=31){d=nb(a,n)|0;if(!d){f=c[n>>2]|0;if(f>>>0<=12){c[b+12>>2]=1<>2]|0;if(f>>>0<=2){c[b+16>>2]=f;b:do if(!f){d=nb(a,n)|0;if(d)break a;f=c[n>>2]|0;if(f>>>0>12){d=1;break a}c[b+20>>2]=1<>2]=(f|0)==1&1;d=ob(a,b+28|0)|0;if(d)break a;d=ob(a,b+32|0)|0;if(d)break a;h=b+36|0;d=nb(a,h)|0;if(d)break a;f=c[h>>2]|0;if(f>>>0>255){d=1;break a}if(!f){c[b+40>>2]=0;break}f=fd(f<<2)|0;g=b+40|0;c[g>>2]=f;if(!f){d=65535;break a}if(c[h>>2]|0){e=0;while(1){d=ob(a,f+(e<<2)|0)|0;e=e+1|0;if(d)break a;if(e>>>0>=(c[h>>2]|0)>>>0)break b;f=c[g>>2]|0}}}while(0);l=b+44|0;d=nb(a,l)|0;if(!d)if((c[l>>2]|0)>>>0<=16?(k=jb(a,1)|0,(k|0)!=-1):0){c[b+48>>2]=(k|0)==1&1;d=nb(a,n)|0;if(!d){e=b+52|0;c[e>>2]=(c[n>>2]|0)+1;d=nb(a,n)|0;if(!d){k=b+56|0;c[k>>2]=(c[n>>2]|0)+1;h=jb(a,1)|0;if((!((h|0)==0|(h|0)==-1)?(jb(a,1)|0)!=-1:0)?(j=jb(a,1)|0,(j|0)!=-1):0){j=(j|0)==1;c[b+60>>2]=j&1;if(j){j=b+64|0;d=nb(a,j)|0;if(d)break;f=b+68|0;d=nb(a,f)|0;if(d)break;h=b+72|0;d=nb(a,h)|0;if(d)break;g=b+76|0;d=nb(a,g)|0;if(d)break;e=c[e>>2]|0;if((c[j>>2]|0)>((e<<3)+~c[f>>2]|0)){d=1;break}f=c[k>>2]|0;if((c[h>>2]|0)>((f<<3)+~c[g>>2]|0)){d=1;break}}else{e=c[e>>2]|0;f=c[k>>2]|0}d=Z(f,e)|0;do switch(c[m>>2]|0){case 11:{f=396;e=345600;g=58;break}case 12:{f=396;e=912384;g=58;break}case 13:{f=396;e=912384;g=58;break}case 20:{f=396;e=912384;g=58;break}case 21:{f=792;e=1824768;g=58;break}case 22:{f=1620;e=3110400;g=58;break}case 30:{f=1620;e=3110400;g=58;break}case 31:{f=3600;e=6912e3;g=58;break}case 32:{f=5120;e=7864320;g=58;break}case 40:{f=8192;e=12582912;g=58;break}case 41:{f=8192;e=12582912;g=58;break}case 42:{f=8704;e=13369344;g=58;break}case 50:{f=22080;e=42393600;g=58;break}case 51:{f=36864;e=70778880;g=58;break}case 10:{f=99;e=152064;g=58;break}default:g=60}while(0);do if((g|0)==58){if(f>>>0>>0){g=60;break}e=(e>>>0)/((d*384|0)>>>0)|0;e=e>>>0<16?e:16;c[n>>2]=e;f=c[l>>2]|0;if(f>>>0>e>>>0){e=f;g=61}}while(0);if((g|0)==60){c[n>>2]=2147483647;e=c[l>>2]|0;g=61}if((g|0)==61)c[n>>2]=e;g=b+88|0;c[g>>2]=e;e=jb(a,1)|0;if((e|0)==-1){d=1;break}n=(e|0)==1;c[b+80>>2]=n&1;do if(n){e=fd(952)|0;f=b+84|0;c[f>>2]=e;if(!e){d=65535;break a}d=Ec(a,e)|0;if(d)break a;d=c[f>>2]|0;if(!(c[d+920>>2]|0))break;e=c[d+948>>2]|0;if((c[d+944>>2]|0)>>>0>e>>>0){d=1;break a}if(e>>>0<(c[l>>2]|0)>>>0){d=1;break a}if(e>>>0>(c[g>>2]|0)>>>0){d=1;break a}c[g>>2]=(e|0)==0?1:e}while(0);Ka(a)|0;d=0}else d=1}}}else d=1}else d=1}}else d=1}}else d=1}else d=1;while(0);i=o;return d|0}function Ra(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;j=i;if((c[a>>2]|0)!=(c[b>>2]|0)){d=1;i=j;return d|0}if((c[a+4>>2]|0)!=(c[b+4>>2]|0)){d=1;i=j;return d|0}if((c[a+12>>2]|0)!=(c[b+12>>2]|0)){d=1;i=j;return d|0}d=c[a+16>>2]|0;if((d|0)!=(c[b+16>>2]|0)){d=1;i=j;return d|0}if((c[a+44>>2]|0)!=(c[b+44>>2]|0)){d=1;i=j;return d|0}if((c[a+48>>2]|0)!=(c[b+48>>2]|0)){d=1;i=j;return d|0}if((c[a+52>>2]|0)!=(c[b+52>>2]|0)){d=1;i=j;return d|0}if((c[a+56>>2]|0)!=(c[b+56>>2]|0)){d=1;i=j;return d|0}h=c[a+60>>2]|0;if((h|0)!=(c[b+60>>2]|0)){d=1;i=j;return d|0}if((c[a+80>>2]|0)!=(c[b+80>>2]|0)){d=1;i=j;return d|0}a:do if(!d){if((c[a+20>>2]|0)!=(c[b+20>>2]|0)){d=1;i=j;return d|0}}else if((d|0)==1){if((c[a+24>>2]|0)!=(c[b+24>>2]|0)){d=1;i=j;return d|0}if((c[a+28>>2]|0)!=(c[b+28>>2]|0)){d=1;i=j;return d|0}if((c[a+32>>2]|0)!=(c[b+32>>2]|0)){d=1;i=j;return d|0}d=c[a+36>>2]|0;if((d|0)!=(c[b+36>>2]|0)){d=1;i=j;return d|0}if(d){e=c[a+40>>2]|0;f=c[b+40>>2]|0;g=0;while(1){if((c[e+(g<<2)>>2]|0)!=(c[f+(g<<2)>>2]|0)){d=1;break}g=g+1|0;if(g>>>0>=d>>>0)break a}i=j;return d|0}}while(0);if(h){if((c[a+64>>2]|0)!=(c[b+64>>2]|0)){d=1;i=j;return d|0}if((c[a+68>>2]|0)!=(c[b+68>>2]|0)){d=1;i=j;return d|0}if((c[a+72>>2]|0)!=(c[b+72>>2]|0)){d=1;i=j;return d|0}if((c[a+76>>2]|0)!=(c[b+76>>2]|0)){d=1;i=j;return d|0}}d=0;i=j;return d|0}function Sa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;i=i+16|0;j=l+4|0;k=l;id(b,0,72);d=nb(a,b)|0;if(d){i=l;return d|0}if((c[b>>2]|0)>>>0>255){d=1;i=l;return d|0}e=b+4|0;d=nb(a,e)|0;if(d){i=l;return d|0}if((c[e>>2]|0)>>>0>31){d=1;i=l;return d|0}if(jb(a,1)|0){d=1;i=l;return d|0}d=jb(a,1)|0;if((d|0)==-1){d=1;i=l;return d|0}c[b+8>>2]=(d|0)==1&1;d=nb(a,j)|0;if(d){i=l;return d|0}d=(c[j>>2]|0)+1|0;h=b+12|0;c[h>>2]=d;if(d>>>0>8){d=1;i=l;return d|0}a:do if(d>>>0>1){d=b+16|0;e=nb(a,d)|0;if(e){d=e;i=l;return d|0}d=c[d>>2]|0;if(d>>>0>6){d=1;i=l;return d|0}switch(d|0){case 5:case 4:case 3:{d=jb(a,1)|0;if((d|0)==-1){d=1;i=l;return d|0}c[b+32>>2]=(d|0)==1&1;d=nb(a,j)|0;if(!d){c[b+36>>2]=(c[j>>2]|0)+1;break a}else{i=l;return d|0}}case 0:{d=fd(c[h>>2]<<2)|0;f=b+20|0;c[f>>2]=d;if(!d){d=65535;i=l;return d|0}if(!(c[h>>2]|0))break a;else e=0;while(1){d=nb(a,j)|0;if(d)break;c[(c[f>>2]|0)+(e<<2)>>2]=(c[j>>2]|0)+1;e=e+1|0;if(e>>>0>=(c[h>>2]|0)>>>0)break a}i=l;return d|0}case 2:{e=b+24|0;c[e>>2]=fd((c[h>>2]<<2)+-4|0)|0;d=fd((c[h>>2]<<2)+-4|0)|0;g=b+28|0;c[g>>2]=d;if((c[e>>2]|0)==0|(d|0)==0){d=65535;i=l;return d|0}if((c[h>>2]|0)==1)break a;else f=0;while(1){d=nb(a,j)|0;if(d){e=46;break}c[(c[e>>2]|0)+(f<<2)>>2]=c[j>>2];d=nb(a,j)|0;if(d){e=46;break}c[(c[g>>2]|0)+(f<<2)>>2]=c[j>>2];f=f+1|0;if(f>>>0>=((c[h>>2]|0)+-1|0)>>>0)break a}if((e|0)==46){i=l;return d|0}break}case 6:{d=nb(a,j)|0;if(d){i=l;return d|0}e=(c[j>>2]|0)+1|0;d=b+40|0;c[d>>2]=e;e=fd(e<<2)|0;g=b+44|0;c[g>>2]=e;if(!e){d=65535;i=l;return d|0}f=c[432+((c[h>>2]|0)+-1<<2)>>2]|0;if(!(c[d>>2]|0))break a;else e=0;while(1){m=jb(a,f)|0;c[(c[g>>2]|0)+(e<<2)>>2]=m;e=e+1|0;if(m>>>0>=(c[h>>2]|0)>>>0){d=1;break}if(e>>>0>=(c[d>>2]|0)>>>0)break a}i=l;return d|0}default:break a}}while(0);d=nb(a,j)|0;if(d){a=d;i=l;return a|0}d=c[j>>2]|0;if(d>>>0>31){a=1;i=l;return a|0}c[b+48>>2]=d+1;d=nb(a,j)|0;if(d){a=d;i=l;return a|0}if((c[j>>2]|0)>>>0>31){a=1;i=l;return a|0}if(jb(a,1)|0){a=1;i=l;return a|0}if((jb(a,2)|0)>>>0>2){a=1;i=l;return a|0}d=ob(a,k)|0;if(d){a=d;i=l;return a|0}d=(c[k>>2]|0)+26|0;if(d>>>0>51){a=1;i=l;return a|0}c[b+52>>2]=d;d=ob(a,k)|0;if(d){a=d;i=l;return a|0}if(((c[k>>2]|0)+26|0)>>>0>51){a=1;i=l;return a|0}d=ob(a,k)|0;if(d){a=d;i=l;return a|0}d=c[k>>2]|0;if((d+12|0)>>>0>24){a=1;i=l;return a|0}c[b+56>>2]=d;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+60>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+64>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+68>>2]=(d|0)==1&1;Ka(a)|0;a=0;i=l;return a|0}function Ta(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=i;i=i+32|0;s=w+20|0;q=w+16|0;o=w+12|0;l=w+8|0;v=w+4|0;t=w;id(b,0,988);u=Z(c[d+56>>2]|0,c[d+52>>2]|0)|0;k=nb(a,v)|0;if(k){f=k;i=w;return f|0}n=c[v>>2]|0;c[b>>2]=n;if(n>>>0>=u>>>0){f=1;i=w;return f|0}k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;m=b+4|0;c[m>>2]=k;if((k|0)==5|(k|0)==0)j=5;else if(!((k|0)==7|(k|0)==2)){f=1;i=w;return f|0}if((j|0)==5){if((c[f>>2]|0)==5){f=1;i=w;return f|0}if(!(c[d+44>>2]|0)){f=1;i=w;return f|0}}k=nb(a,v)|0;if(k){f=k;i=w;return f|0}n=c[v>>2]|0;c[b+8>>2]=n;if((n|0)!=(c[e>>2]|0)){f=1;i=w;return f|0}n=d+12|0;k=c[n>>2]|0;j=0;while(1)if(!(k>>>j))break;else j=j+1|0;k=jb(a,j+-1|0)|0;if((k|0)==-1){f=1;i=w;return f|0}j=(c[f>>2]|0)==5;if(j&(k|0)!=0){f=1;i=w;return f|0}c[b+12>>2]=k;if(j){k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;c[b+16>>2]=k;if(k>>>0>65535){f=1;i=w;return f|0}}g=d+16|0;k=c[g>>2]|0;if(!k){h=d+20|0;k=c[h>>2]|0;j=0;while(1)if(!(k>>>j))break;else j=j+1|0;k=jb(a,j+-1|0)|0;if((k|0)==-1){f=1;i=w;return f|0}j=b+20|0;c[j>>2]=k;do if(c[e+8>>2]|0){k=ob(a,t)|0;if(!k){c[b+24>>2]=c[t>>2];break}else{f=k;i=w;return f|0}}while(0);if((c[f>>2]|0)==5){k=c[j>>2]|0;if(k>>>0>(c[h>>2]|0)>>>1>>>0){f=1;i=w;return f|0}j=c[b+24>>2]|0;if((k|0)!=(((j|0)>0?0:0-j|0)|0)){f=1;i=w;return f|0}}k=c[g>>2]|0}if((k|0)==1?(c[d+24>>2]|0)==0:0){k=ob(a,t)|0;if(k){f=k;i=w;return f|0}k=b+28|0;c[k>>2]=c[t>>2];do if(c[e+8>>2]|0){j=ob(a,t)|0;if(!j){c[b+32>>2]=c[t>>2];break}else{f=j;i=w;return f|0}}while(0);if((c[f>>2]|0)==5?(j=c[k>>2]|0,k=(c[d+32>>2]|0)+j+(c[b+32>>2]|0)|0,(((j|0)<(k|0)?j:k)|0)!=0):0){f=1;i=w;return f|0}}if(c[e+68>>2]|0){k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;c[b+36>>2]=k;if(k>>>0>127){f=1;i=w;return f|0}}k=c[m>>2]|0;if((k|0)==5|(k|0)==0){k=jb(a,1)|0;if((k|0)==-1){f=1;i=w;return f|0}c[b+40>>2]=k;do if(!k){k=c[e+48>>2]|0;if(k>>>0>16){f=1;i=w;return f|0}else{c[b+44>>2]=k;break}}else{k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;if(k>>>0>15){f=1;i=w;return f|0}else{c[b+44>>2]=k+1;break}}while(0);k=c[m>>2]|0}do if((k|0)==5|(k|0)==0){g=c[b+44>>2]|0;j=c[n>>2]|0;k=jb(a,1)|0;if((k|0)==-1){f=1;i=w;return f|0}c[b+68>>2]=k;if(k){h=0;a:while(1){if(h>>>0>g>>>0){r=1;j=110;break}k=nb(a,l)|0;if(k){r=k;j=110;break}k=c[l>>2]|0;if(k>>>0>3){r=1;j=110;break}c[b+(h*12|0)+72>>2]=k;do if(k>>>0<2){k=nb(a,o)|0;if(k){r=k;j=110;break a}k=c[o>>2]|0;if(k>>>0>=j>>>0){r=1;j=110;break a}c[b+(h*12|0)+76>>2]=k+1}else{if((k|0)!=2)break;k=nb(a,o)|0;if(k){r=k;j=110;break a}c[b+(h*12|0)+80>>2]=c[o>>2]}while(0);if((c[l>>2]|0)==3){j=61;break}else h=h+1|0}if((j|0)==61){if(!h)r=1;else break;i=w;return r|0}else if((j|0)==110){i=w;return r|0}}}while(0);do if(c[f+4>>2]|0){n=c[d+44>>2]|0;f=(c[f>>2]|0)==5;k=jb(a,1)|0;j=(k|0)==-1;if(f){if(j){f=1;i=w;return f|0}c[b+276>>2]=k;g=jb(a,1)|0;if((g|0)==-1){f=1;i=w;return f|0}c[b+280>>2]=g;if((n|0)!=0|(g|0)==0)break;else r=1;i=w;return r|0}if(j){f=1;i=w;return f|0}c[b+284>>2]=k;if(k){j=(n<<1)+2|0;h=0;d=0;g=0;l=0;m=0;while(1){if(h>>>0>j>>>0){r=1;j=110;break}k=nb(a,q)|0;if(k){r=k;j=110;break}k=c[q>>2]|0;if(k>>>0>6){r=1;j=110;break}c[b+(h*20|0)+288>>2]=k;if((k&-3|0)==1){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+292>>2]=(c[s>>2]|0)+1;k=c[q>>2]|0}if((k|0)==2){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+296>>2]=c[s>>2];k=c[q>>2]|0}if((k|0)==3|(k|0)==6){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+300>>2]=c[s>>2];k=c[q>>2]|0}if((k|0)==4){k=nb(a,s)|0;if(k){r=k;j=110;break}k=c[s>>2]|0;if(k>>>0>n>>>0){r=1;j=110;break}if(!k)c[b+(h*20|0)+304>>2]=65535;else c[b+(h*20|0)+304>>2]=k+-1;k=c[q>>2]|0;p=g+1|0}else p=g;l=((k|0)==5&1)+l|0;d=((k|0)!=0&k>>>0<4&1)+d|0;m=((k|0)==6&1)+m|0;if(!k){j=90;break}else{h=h+1|0;g=p}}if((j|0)==90){if(p>>>0>1|l>>>0>1|m>>>0>1){f=1;i=w;return f|0}if((d|0)!=0&(l|0)!=0)r=1;else break;i=w;return r|0}else if((j|0)==110){i=w;return r|0}}}while(0);g=ob(a,t)|0;if(g){f=g;i=w;return f|0}f=c[t>>2]|0;c[b+48>>2]=f;f=f+(c[e+52>>2]|0)|0;c[t>>2]=f;if(f>>>0>51){f=1;i=w;return f|0}do if(c[e+60>>2]|0){g=nb(a,v)|0;if(g){f=g;i=w;return f|0}g=c[v>>2]|0;c[b+52>>2]=g;if(g>>>0>2){f=1;i=w;return f|0}if((g|0)==1)break;g=ob(a,t)|0;if(g){f=g;i=w;return f|0}g=c[t>>2]|0;if((g+6|0)>>>0>12){f=1;i=w;return f|0}c[b+56>>2]=g<<1;g=ob(a,t)|0;if(g){f=g;i=w;return f|0}g=c[t>>2]|0;if((g+6|0)>>>0>12){f=1;i=w;return f|0}else{c[b+60>>2]=g<<1;break}}while(0);do if((c[e+12>>2]|0)>>>0>1?((c[e+16>>2]|0)+-3|0)>>>0<3:0){k=e+36|0;j=c[k>>2]|0;j=(((u>>>0)%(j>>>0)|0|0)==0?1:2)+((u>>>0)/(j>>>0)|0)|0;h=0;while(1){g=h+1|0;if(!(-1<>2]=g;if((g|0)==-1){f=1;i=w;return f|0}c[b+64>>2]=g;f=c[k>>2]|0;if(g>>>0>(((u+-1+f|0)>>>0)/(f>>>0)|0)>>>0)r=1;else break;i=w;return r|0}while(0);f=0;i=w;return f|0}function Ua(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;i=i+32|0;e=f+20|0;d=f;c[d+0>>2]=c[a+0>>2];c[d+4>>2]=c[a+4>>2];c[d+8>>2]=c[a+8>>2];c[d+12>>2]=c[a+12>>2];c[d+16>>2]=c[a+16>>2];a=nb(d,e)|0;if(!a){a=nb(d,e)|0;if(!a){a=nb(d,e)|0;if(!a){a=c[e>>2]|0;if(a>>>0>255)a=1;else{c[b>>2]=a;a=0}}}}i=f;return a|0}function Va(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+32|0;e=g+20|0;f=g;c[f+0>>2]=c[a+0>>2];c[f+4>>2]=c[a+4>>2];c[f+8>>2]=c[a+8>>2];c[f+12>>2]=c[a+12>>2];c[f+16>>2]=c[a+16>>2];a=nb(f,e)|0;if(a){i=g;return a|0}a=nb(f,e)|0;if(a){i=g;return a|0}a=nb(f,e)|0;if(!a)a=0;else{i=g;return a|0}while(1)if(!(b>>>a))break;else a=a+1|0;a=jb(f,a+-1|0)|0;if((a|0)==-1){a=1;i=g;return a|0}c[d>>2]=a;a=0;i=g;return a|0}function Wa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;h=i;i=i+32|0;f=h+20|0;g=h;if((d|0)!=5){d=1;i=h;return d|0};c[g+0>>2]=c[a+0>>2];c[g+4>>2]=c[a+4>>2];c[g+8>>2]=c[a+8>>2];c[g+12>>2]=c[a+12>>2];c[g+16>>2]=c[a+16>>2];d=nb(g,f)|0;if(d){i=h;return d|0}d=nb(g,f)|0;if(d){i=h;return d|0}d=nb(g,f)|0;if(!d)d=0;else{i=h;return d|0}while(1)if(!(b>>>d))break;else d=d+1|0;if((jb(g,d+-1|0)|0)==-1){d=1;i=h;return d|0}d=nb(g,e)|0;i=h;return d|0}function Xa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;k=i;i=i+32|0;h=k+20|0;j=k;c[j+0>>2]=c[a+0>>2];c[j+4>>2]=c[a+4>>2];c[j+8>>2]=c[a+8>>2];c[j+12>>2]=c[a+12>>2];c[j+16>>2]=c[a+16>>2];a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=c[b+12>>2]|0;f=0;while(1)if(!(a>>>f))break;else f=f+1|0;if((jb(j,f+-1|0)|0)==-1){f=1;i=k;return f|0}if((d|0)==5?(g=nb(j,h)|0,(g|0)!=0):0){f=g;i=k;return f|0}f=c[b+20>>2]|0;a=0;while(1)if(!(f>>>a))break;else a=a+1|0;f=jb(j,a+-1|0)|0;if((f|0)==-1){f=1;i=k;return f|0}c[e>>2]=f;f=0;i=k;return f|0}function Ya(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;k=i;i=i+32|0;h=k+20|0;j=k;c[j+0>>2]=c[a+0>>2];c[j+4>>2]=c[a+4>>2];c[j+8>>2]=c[a+8>>2];c[j+12>>2]=c[a+12>>2];c[j+16>>2]=c[a+16>>2];a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=c[b+12>>2]|0;f=0;while(1)if(!(a>>>f))break;else f=f+1|0;if((jb(j,f+-1|0)|0)==-1){f=1;i=k;return f|0}if((d|0)==5?(g=nb(j,h)|0,(g|0)!=0):0){f=g;i=k;return f|0}f=c[b+20>>2]|0;a=0;while(1)if(!(f>>>a))break;else a=a+1|0;if((jb(j,a+-1|0)|0)==-1){f=1;i=k;return f|0}f=ob(j,e)|0;i=k;return f|0}function Za(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0;m=i;i=i+32|0;j=m+20|0;l=m;c[l+0>>2]=c[a+0>>2];c[l+4>>2]=c[a+4>>2];c[l+8>>2]=c[a+8>>2];c[l+12>>2]=c[a+12>>2];c[l+16>>2]=c[a+16>>2];g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=c[b+12>>2]|0;a=0;while(1)if(!(g>>>a))break;else a=a+1|0;if((jb(l,a+-1|0)|0)==-1){l=1;i=m;return l|0}if((d|0)==5?(h=nb(l,j)|0,(h|0)!=0):0){l=h;i=m;return l|0}g=ob(l,f)|0;if(g){l=g;i=m;return l|0}if((e|0)!=0?(k=ob(l,f+4|0)|0,(k|0)!=0):0){l=k;i=m;return l|0}l=0;i=m;return l|0}function _a(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;m=i;i=i+32|0;l=m+24|0;j=m+20|0;k=m;c[k+0>>2]=c[b+0>>2];c[k+4>>2]=c[b+4>>2];c[k+8>>2]=c[b+8>>2];c[k+12>>2]=c[b+12>>2];c[k+16>>2]=c[b+16>>2];f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=c[d+12>>2]|0;b=0;while(1)if(!(f>>>b))break;else b=b+1|0;if((jb(k,b+-1|0)|0)==-1){n=1;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}g=d+16|0;f=c[g>>2]|0;if(!f){b=c[d+20>>2]|0;f=0;while(1)if(!(b>>>f))break;else f=f+1|0;if((jb(k,f+-1|0)|0)==-1){n=1;i=m;return n|0}if((c[e+8>>2]|0)!=0?(h=ob(k,j)|0,(h|0)!=0):0){n=h;i=m;return n|0}f=c[g>>2]|0}if((f|0)==1?(c[d+24>>2]|0)==0:0){f=ob(k,j)|0;if(f){n=f;i=m;return n|0}if((c[e+8>>2]|0)!=0?(n=ob(k,j)|0,(n|0)!=0):0){i=m;return n|0}}if((c[e+68>>2]|0)!=0?(o=nb(k,l)|0,(o|0)!=0):0){n=o;i=m;return n|0}n=jb(k,1)|0;c[a>>2]=n;n=(n|0)==-1&1;i=m;return n|0}function $a(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;C=i;i=i+448|0;p=C+8|0;x=C+4|0;v=C;p=p+(0-p&15)|0;n=c[b+3376>>2]|0;j=c[e>>2]|0;c[x>>2]=0;y=b+1192|0;c[y>>2]=(c[y>>2]|0)+1;q=b+1200|0;c[q>>2]=0;o=b+12|0;c[v>>2]=(c[e+48>>2]|0)+(c[(c[o>>2]|0)+52>>2]|0);w=e+36|0;r=b+1212|0;s=e+52|0;t=e+56|0;u=e+60|0;z=e+4|0;l=e+44|0;h=b+1220|0;m=b+1172|0;B=b+1176|0;k=n+12|0;A=0;f=0;while(1){e=c[r>>2]|0;if((c[w>>2]|0)==0?(c[e+(j*216|0)+196>>2]|0)!=0:0){f=1;e=22;break}g=c[(c[o>>2]|0)+56>>2]|0;F=c[s>>2]|0;E=c[t>>2]|0;D=c[u>>2]|0;c[e+(j*216|0)+4>>2]=c[y>>2];c[e+(j*216|0)+8>>2]=F;c[e+(j*216|0)+12>>2]=E;c[e+(j*216|0)+16>>2]=D;c[e+(j*216|0)+24>>2]=g;e=c[z>>2]|0;if((e|0)!=2?!((e|0)==7|(f|0)!=0):0){f=nb(a,x)|0;if(f){e=22;break}e=c[x>>2]|0;if(e>>>0>((c[B>>2]|0)-j|0)>>>0){f=1;e=22;break}if(!e)f=0;else{id(k,0,164);c[n>>2]=0;f=1}}e=c[x>>2]|0;if(!e){f=bb(a,n,(c[r>>2]|0)+(j*216|0)|0,c[z>>2]|0,c[l>>2]|0)|0;if(!f)g=0;else{e=22;break}}else{c[x>>2]=e+-1;g=f}f=gb((c[r>>2]|0)+(j*216|0)|0,n,d,h,v,j,c[(c[o>>2]|0)+64>>2]|0,p)|0;if(f){e=22;break}A=((c[(c[r>>2]|0)+(j*216|0)+196>>2]|0)==1&1)+A|0;if(!(La(a)|0))e=(c[x>>2]|0)!=0;else e=1;f=c[z>>2]|0;if((f|0)==7|(f|0)==2)c[q>>2]=j;j=Ma(c[m>>2]|0,c[B>>2]|0,j)|0;if(!((j|0)!=0|e^1)){f=1;e=22;break}if(!e){e=20;break}else f=g}if((e|0)==20){e=b+1196|0;f=(c[e>>2]|0)+A|0;if(f>>>0>(c[B>>2]|0)>>>0){y=1;i=C;return y|0}c[e>>2]=f;y=0;i=C;return y|0}else if((e|0)==22){i=C;return f|0}return 0}function ab(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;h=c[a+1192>>2]|0;d=c[a+1200>>2]|0;j=a+1212|0;a:do if(!d)d=b;else{e=a+16|0;f=0;do{do{d=d+-1|0;if(d>>>0<=b>>>0)break a}while((c[(c[j>>2]|0)+(d*216|0)+4>>2]|0)!=(h|0));f=f+1|0;g=c[(c[e>>2]|0)+52>>2]|0}while(f>>>0<(g>>>0>10?g:10)>>>0)}while(0);g=a+1172|0;b=a+1176|0;while(1){e=c[j>>2]|0;if((c[e+(d*216|0)+4>>2]|0)!=(h|0)){d=11;break}f=e+(d*216|0)+196|0;e=c[f>>2]|0;if(!e){d=11;break}c[f>>2]=e+-1;d=Ma(c[g>>2]|0,c[b>>2]|0,d)|0;if(!d){d=11;break}}if((d|0)==11){i=k;return}}function bb(a,d,e,f,g){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;B=i;i=i+32|0;u=B+20|0;v=B+16|0;q=B+12|0;p=B+8|0;z=B+4|0;y=B;id(d,0,2088);l=nb(a,z)|0;m=c[z>>2]|0;do if((f|0)==2|(f|0)==7){m=m+6|0;if(m>>>0>31|(l|0)!=0){e=1;i=B;return e|0}else{c[d>>2]=m;o=m;break}}else{m=m+1|0;if(m>>>0>31|(l|0)!=0){e=1;i=B;return e|0}else{c[d>>2]=m;o=m;break}}while(0);a:do if((o|0)!=31){b:do if(o>>>0>=6){o=(o|0)!=6;p=o&1;if(!p){c[v>>2]=0;q=0;while(1){f=kb(a)|0;c[u>>2]=f;t=f>>>31;c[d+(q<<2)+12>>2]=t;if(!t){c[d+(q<<2)+76>>2]=f>>>28&7;m=f<<4;n=1}else{m=f<<1;n=0}f=q|1;t=m>>>31;c[d+(f<<2)+12>>2]=t;if(!t){c[d+(f<<2)+76>>2]=m>>>28&7;l=m<<4;n=n+1|0}else l=m<<1;m=f+1|0;t=l>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=l>>>28&7;m=l<<4;n=n+1|0}else m=l<<1;l=q|3;t=m>>>31;c[d+(l<<2)+12>>2]=t;if(!t){c[d+(l<<2)+76>>2]=m>>>28&7;f=m<<4;n=n+1|0}else f=m<<1;m=l+1|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=l+2|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=l+3|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=q|7;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;m=f<<4;n=n+1|0}else m=f<<1;c[u>>2]=m;if((lb(a,(n*3|0)+8|0)|0)==-1){w=1;t=68;break b}t=(c[v>>2]|0)+1|0;c[v>>2]=t;if((t|0)<2)q=q+8|0;else{t=52;break}}}else if((p|0)==1)t=52;if((t|0)==52){v=(nb(a,u)|0)!=0;l=c[u>>2]|0;if(v|l>>>0>3){w=1;t=68;break}c[d+140>>2]=l}if(o){v=c[d>>2]|0;s=v+-7|0;u=s>>>2;c[d+4>>2]=(s>>>0>11?u+268435453|0:u)<<4|(v>>>0>18?15:0)}else{x=p;t=70}}else{if((o|0)==0|(o|0)==1){r=v;s=u}else if(!((o|0)==3|(o|0)==2)){f=0;do{l=(nb(a,q)|0)!=0;m=c[q>>2]|0;if(l|m>>>0>3){n=1;t=96;break}c[d+(f<<2)+176>>2]=m;f=f+1|0}while(f>>>0<4);if((t|0)==96){i=B;return n|0}c:do if(g>>>0>1&(o|0)!=5){m=g>>>0>2&1;f=0;while(1){if(qb(a,q,m)|0){n=1;t=96;break}n=c[q>>2]|0;if(n>>>0>=g>>>0){n=1;t=96;break}c[d+(f<<2)+192>>2]=n;f=f+1|0;if(f>>>0>=4){h=0;break c}}if((t|0)==96){i=B;return n|0}}else h=0;while(0);d:while(1){n=c[d+(h<<2)+176>>2]|0;if(!n)n=0;else if((n|0)==2|(n|0)==1)n=1;else n=3;c[q>>2]=n;m=0;while(1){n=ob(a,p)|0;if(n){t=96;break d}b[d+(h<<4)+(m<<2)+208>>1]=c[p>>2];n=ob(a,p)|0;if(n){t=96;break d}b[d+(h<<4)+(m<<2)+210>>1]=c[p>>2];t=c[q>>2]|0;c[q>>2]=t+-1;if(!t)break;else m=m+1|0}h=h+1|0;if(h>>>0>=4){x=2;t=70;break b}}if((t|0)==96){i=B;return n|0}}else{r=v;s=u}if(g>>>0>1){if((o|0)==0|(o|0)==1)n=0;else if((o|0)==3|(o|0)==2)n=1;else n=3;l=g>>>0>2&1;f=0;while(1){if(qb(a,u,l)|0){w=1;t=68;break b}m=c[u>>2]|0;if(m>>>0>=g>>>0){w=1;t=68;break b}c[d+(f<<2)+144>>2]=m;if(!n)break;else{n=n+-1|0;f=f+1|0}}}if((o|0)==0|(o|0)==1){l=0;m=0}else if((o|0)==3|(o|0)==2){l=1;m=0}else{l=3;m=0}while(1){f=ob(a,v)|0;if(f){w=f;t=68;break b}b[d+(m<<2)+160>>1]=c[v>>2];f=ob(a,v)|0;if(f){w=f;t=68;break b}b[d+(m<<2)+162>>1]=c[v>>2];if(!l){x=2;t=70;break}else{l=l+-1|0;m=m+1|0}}}while(0);if((t|0)==68){e=w;i=B;return e|0}do if((t|0)==70){h=pb(a,z,(x|0)==0&1)|0;if(!h){z=c[z>>2]|0;c[d+4>>2]=z;if(!z)break a;else break}else{e=h;i=B;return e|0}}while(0);z=(ob(a,y)|0)!=0;h=c[y>>2]|0;if(z|(h|0)<-26|(h|0)>25){e=1;i=B;return e|0}c[d+8>>2]=h;l=c[d+4>>2]|0;o=d+272|0;e:do if((c[d>>2]|0)>>>0>=7){h=rb(a,d+1864|0,ib(e,0,o)|0,16)|0;if(!(h&15)){b[d+320>>1]=h>>>4&255;h=0;m=3;while(1){n=l>>>1;if(!(l&1))h=h+4|0;else{f=3;while(1){l=rb(a,d+(h<<6)+332|0,ib(e,h,o)|0,15)|0;c[d+(h<<2)+1992>>2]=l>>>15;if(l&15){j=l;break e}b[d+(h<<1)+272>>1]=l>>>4&255;h=h+1|0;if(!f)break;else f=f+-1|0}}if(!m){k=h;A=n;t=87;break}else{l=n;m=m+-1|0}}}else j=h}else{h=0;m=3;while(1){n=l>>>1;if(!(l&1))h=h+4|0;else{f=3;while(1){l=rb(a,d+(h<<6)+328|0,ib(e,h,o)|0,16)|0;c[d+(h<<2)+1992>>2]=l>>>16;if(l&15){j=l;break e}b[d+(h<<1)+272>>1]=l>>>4&255;h=h+1|0;if(!f)break;else f=f+-1|0}}if(!m){k=h;A=n;t=87;break}else{l=n;m=m+-1|0}}}while(0);f:do if((t|0)==87){if(A&3){j=rb(a,d+1928|0,-1,4)|0;if(j&15)break;b[d+322>>1]=j>>>4&255;j=rb(a,d+1944|0,-1,4)|0;if(j&15)break;b[d+324>>1]=j>>>4&255}if(!(A&2))j=0;else{h=7;while(1){j=rb(a,d+(k<<6)+332|0,ib(e,k,o)|0,15)|0;if(j&15)break f;b[d+(k<<1)+272>>1]=j>>>4&255;c[d+(k<<2)+1992>>2]=j>>>15;if(!h){j=0;break}else{k=k+1|0;h=h+-1|0}}}}while(0);c[a+16>>2]=((c[a+4>>2]|0)-(c[a>>2]|0)<<3)+(c[a+8>>2]|0);if(j){e=j;i=B;return e|0}}else{while(1){if(mb(a)|0)break;if(jb(a,1)|0){n=1;t=96;break}}if((t|0)==96){i=B;return n|0}k=0;j=d+328|0;while(1){h=jb(a,8)|0;c[z>>2]=h;if((h|0)==-1){n=1;break}c[j>>2]=h;k=k+1|0;if(k>>>0>=384)break a;else j=j+4|0}i=B;return n|0}while(0);e=0;i=B;return e|0}function cb(a){a=a|0;if(a>>>0<6)a=2;else a=(a|0)!=6&1;return a|0}function db(a){a=a|0;var b=0;b=i;if((a|0)==0|(a|0)==1)a=1;else if((a|0)==3|(a|0)==2)a=2;else a=4;i=b;return a|0}function eb(a){a=a|0;var b=0;b=i;if(!a)a=1;else if((a|0)==2|(a|0)==1)a=2;else a=4;i=b;return a|0}function fb(a){a=a|0;return a+1&3|0}function gb(d,e,f,g,h,j,k,l){d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=i;s=c[e>>2]|0;c[d>>2]=s;o=d+196|0;c[o>>2]=(c[o>>2]|0)+1;Na(f,j);if((s|0)==31){m=d+28|0;c[d+20>>2]=0;if((c[o>>2]|0)>>>0>1){b[m>>1]=16;b[d+30>>1]=16;b[d+32>>1]=16;b[d+34>>1]=16;b[d+36>>1]=16;b[d+38>>1]=16;b[d+40>>1]=16;b[d+42>>1]=16;b[d+44>>1]=16;b[d+46>>1]=16;b[d+48>>1]=16;b[d+50>>1]=16;b[d+52>>1]=16;b[d+54>>1]=16;b[d+56>>1]=16;b[d+58>>1]=16;b[d+60>>1]=16;b[d+62>>1]=16;b[d+64>>1]=16;b[d+66>>1]=16;b[d+68>>1]=16;b[d+70>>1]=16;b[d+72>>1]=16;b[d+74>>1]=16;t=0;i=v;return t|0}o=23;h=e+328|0;n=l;while(1){b[m>>1]=16;a[n>>0]=c[h>>2];a[n+1>>0]=c[h+4>>2];a[n+2>>0]=c[h+8>>2];a[n+3>>0]=c[h+12>>2];a[n+4>>0]=c[h+16>>2];a[n+5>>0]=c[h+20>>2];a[n+6>>0]=c[h+24>>2];a[n+7>>0]=c[h+28>>2];a[n+8>>0]=c[h+32>>2];a[n+9>>0]=c[h+36>>2];a[n+10>>0]=c[h+40>>2];a[n+11>>0]=c[h+44>>2];a[n+12>>0]=c[h+48>>2];a[n+13>>0]=c[h+52>>2];a[n+14>>0]=c[h+56>>2];a[n+15>>0]=c[h+60>>2];if(!o)break;else{o=o+-1|0;h=h+64|0;n=n+16|0;m=m+2|0}}sc(f,l);t=0;i=v;return t|0}m=d+28|0;if(s){hd(m,e+272|0,54);n=c[e+8>>2]|0;o=c[h>>2]|0;do if(n){o=o+n|0;c[h>>2]=o;if((o|0)<0){o=o+52|0;c[h>>2]=o;break}if((o|0)>51){o=o+-52|0;c[h>>2]=o}}while(0);r=d+20|0;c[r>>2]=o;n=e+328|0;h=e+1992|0;a:do if((c[d>>2]|0)>>>0<7){q=15;o=m;while(1){if(b[o>>1]|0){if(Ga(n,c[r>>2]|0,0,c[h>>2]|0)|0){m=1;break}}else c[n>>2]=16777215;n=n+64|0;o=o+2|0;h=h+4|0;if(!q)break a;else q=q+-1|0}i=v;return m|0}else{if(!(b[d+76>>1]|0)){q=464;p=15;o=m}else{Ha(e+1864|0,o);q=464;p=15;o=m}while(1){m=c[e+(c[q>>2]<<2)+1864>>2]|0;q=q+4|0;c[n>>2]=m;if((m|0)==0?(b[o>>1]|0)==0:0)c[n>>2]=16777215;else u=18;if((u|0)==18?(u=0,(Ga(n,c[r>>2]|0,1,c[h>>2]|0)|0)!=0):0){m=1;break}n=n+64|0;o=o+2|0;h=h+4|0;if(!p)break a;else p=p+-1|0}i=v;return m|0}while(0);q=c[192+((Oa(0,51,(c[d+24>>2]|0)+(c[r>>2]|0)|0)|0)<<2)>>2]|0;if((b[d+78>>1]|0)==0?(b[d+80>>1]|0)==0:0){p=e+1928|0;m=7}else{p=e+1928|0;Ia(p,q);m=7}while(1){r=c[p>>2]|0;p=p+4|0;c[n>>2]=r;if((r|0)==0?(b[o>>1]|0)==0:0)c[n>>2]=16777215;else u=31;if((u|0)==31?(u=0,(Ga(n,q,1,c[h>>2]|0)|0)!=0):0){m=1;u=39;break}if(!m)break;else{n=n+64|0;h=h+4|0;m=m+-1|0;o=o+2|0}}if((u|0)==39){i=v;return m|0}if(s>>>0>=6){o=Mb(d,e,f,j,k,l)|0;if(o){t=o;i=v;return t|0}}else u=37}else{id(m,0,54);c[d+20>>2]=c[h>>2];u=37}if((u|0)==37?(t=Sb(d,e,g,j,f,l)|0,(t|0)!=0):0){i=v;return t|0}t=0;i=v;return t|0}function hb(a){a=a|0;return a|0}function ib(d,e,f){d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0;k=i;l=vb(e)|0;g=wb(e)|0;h=a[l+4>>0]|0;j=a[g+4>>0]|0;g=(c[g>>2]|0)==4;if((c[l>>2]|0)==4){e=b[f+((h&255)<<1)>>1]|0;if(g){e=e+1+(b[f+((j&255)<<1)>>1]|0)>>1;i=k;return e|0}g=d+204|0;if(!(zb(d,c[g>>2]|0)|0)){i=k;return e|0}e=e+1+(b[(c[g>>2]|0)+((j&255)<<1)+28>>1]|0)>>1;i=k;return e|0}if(g){e=b[f+((j&255)<<1)>>1]|0;g=d+200|0;if(!(zb(d,c[g>>2]|0)|0)){i=k;return e|0}e=e+1+(b[(c[g>>2]|0)+((h&255)<<1)+28>>1]|0)>>1;i=k;return e|0}g=d+200|0;if(!(zb(d,c[g>>2]|0)|0)){h=0;f=0}else{h=b[(c[g>>2]|0)+((h&255)<<1)+28>>1]|0;f=1}g=d+204|0;if(!(zb(d,c[g>>2]|0)|0)){e=h;i=k;return e|0}e=b[(c[g>>2]|0)+((j&255)<<1)+28>>1]|0;if(!f){i=k;return e|0}e=h+1+e>>1;i=k;return e|0}function jb(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;n=a+4|0;j=c[n>>2]|0;m=c[a+12>>2]<<3;o=a+16|0;l=c[o>>2]|0;g=m-l|0;if((g|0)>31){e=a+8|0;g=c[e>>2]|0;f=(d[j+1>>0]|0)<<16|(d[j>>0]|0)<<24|(d[j+2>>0]|0)<<8|(d[j+3>>0]|0);if(!g)h=e;else{h=e;f=(d[j+4>>0]|0)>>>(8-g|0)|f<0){e=c[h>>2]|0;k=e+24|0;f=(d[j>>0]|0)<0){e=g;g=k;do{j=j+1|0;g=g+-8|0;f=(d[j>>0]|0)<0)}}else f=0}e=l+b|0;c[o>>2]=e;c[h>>2]=e&7;if(e>>>0>m>>>0){n=-1;i=p;return n|0}c[n>>2]=(c[a>>2]|0)+(e>>>3);n=f>>>(32-b|0);i=p;return n|0}function kb(a){a=a|0;var b=0,e=0,f=0,g=0,h=0;g=i;f=c[a+4>>2]|0;e=(c[a+12>>2]<<3)-(c[a+16>>2]|0)|0;if((e|0)>31){b=c[a+8>>2]|0;a=(d[f+1>>0]|0)<<16|(d[f>>0]|0)<<24|(d[f+2>>0]|0)<<8|(d[f+3>>0]|0);if(!b){b=a;i=g;return b|0}b=(d[f+4>>0]|0)>>>(8-b|0)|a<>2]|0;a=h+24|0;b=(d[f>>0]|0)<>0]|0)<0);i=g;return b|0}function lb(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;e=a+16|0;b=(c[e>>2]|0)+b|0;c[e>>2]=b;c[a+8>>2]=b&7;if(b>>>0>c[a+12>>2]<<3>>>0){b=-1;i=d;return b|0}c[a+4>>2]=(c[a>>2]|0)+(b>>>3);b=0;i=d;return b|0}function mb(a){a=a|0;return (c[a+8>>2]|0)==0|0}function nb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=i;d=kb(a)|0;do if((d|0)>=0){if(d>>>0>1073741823){if((lb(a,3)|0)==-1){d=1;break}c[b>>2]=(d>>>29&1)+1;d=0;break}if(d>>>0>536870911){if((lb(a,5)|0)==-1){d=1;break}c[b>>2]=(d>>>27&3)+3;d=0;break}if(d>>>0>268435455){if((lb(a,7)|0)==-1){d=1;break}c[b>>2]=(d>>>25&7)+7;d=0;break}d=Ja(d,28)|0;e=d+4|0;if((e|0)!=32){lb(a,d+5|0)|0;d=jb(a,e)|0;if((d|0)==-1){d=1;break}c[b>>2]=(1<>2]=0;lb(a,32)|0;if((jb(a,1)|0)==1?(f=kb(a)|0,(lb(a,32)|0)!=-1):0)if((f|0)==1){c[b>>2]=-1;d=1;break}else if(!f){c[b>>2]=-1;d=0;break}else{d=1;break}else d=1}else{lb(a,1)|0;c[b>>2]=0;d=0}while(0);i=g;return d|0}function ob(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;f=e;c[f>>2]=0;d=nb(a,f)|0;a=c[f>>2]|0;d=(d|0)==0;if((a|0)==-1)if(d)a=1;else{c[b>>2]=-2147483648;a=0}else if(d){d=(a+1|0)>>>1;c[b>>2]=(a&1|0)!=0?d:0-d|0;a=0}else a=1;i=e;return a|0}function pb(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0;g=i;i=i+16|0;f=g;if(nb(a,f)|0){f=1;i=g;return f|0}f=c[f>>2]|0;if(f>>>0>47){f=1;i=g;return f|0}c[b>>2]=d[((e|0)==0?576:528)+f>>0];f=0;i=g;return f|0}function qb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=i;if(!d){d=jb(a,1)|0;c[b>>2]=d;if((d|0)==-1)d=1;else{c[b>>2]=d^1;d=0}}else d=nb(a,b)|0;i=e;return d|0}function rb(a,b,f,g){a=a|0;b=b|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0;O=i;i=i+128|0;M=O+64|0;N=O;n=kb(a)|0;p=n>>>16;do if(f>>>0<2)if((n|0)>=0){if(n>>>0>201326591){o=e[1264+(n>>>26<<1)>>1]|0;k=25;break}if(n>>>0>16777215){o=e[1328+(n>>>22<<1)>>1]|0;k=25;break}if(n>>>0>2097151){o=e[1424+((n>>>18)+-8<<1)>>1]|0;k=25;break}else{o=e[1536+(p<<1)>>1]|0;k=25;break}}else q=1;else if(f>>>0<4){if((n|0)<0){q=(p&16384|0)!=0?2:2082;break}if(n>>>0>268435455){o=e[1600+(n>>>26<<1)>>1]|0;k=25;break}if(n>>>0>33554431){o=e[1664+(n>>>23<<1)>>1]|0;k=25;break}else{o=e[1728+(n>>>18<<1)>>1]|0;k=25;break}}else{if(f>>>0<8){f=n>>>26;if((f+-8|0)>>>0<56){o=e[1984+(f<<1)>>1]|0;k=25;break}o=e[2112+(n>>>22<<1)>>1]|0;k=25;break}if(f>>>0<17){o=e[2368+(n>>>26<<1)>>1]|0;k=25;break}f=n>>>29;if(f){o=e[2496+(f<<1)>>1]|0;k=25;break}o=e[2512+(n>>>24<<1)>>1]|0;k=25;break}while(0);if((k|0)==25)if(!o){C=1;i=O;return C|0}else q=o;o=q&31;f=n<>>11&31;if(I>>>0>g>>>0){C=1;i=O;return C|0}v=q>>>5&63;do if(I){if(!v)o=0;else{do if(p>>>0>>0)if((lb(a,o)|0)==-1){C=1;i=O;return C|0}else{p=32;f=kb(a)|0;break}while(0);n=f>>>(32-v|0);f=f<>2]=(o&n|0)!=0?-1:1;o=o>>>1;k=k+1|0}while((o|0)!=0);p=p-v|0;o=k}u=v>>>0<3;a:do if(o>>>0>>0){t=o;s=I>>>0>10&u&1;b:while(1){if(p>>>0<16){if((lb(a,32-p|0)|0)==-1){J=1;k=127;break}r=32;f=kb(a)|0}else r=p;do if((f|0)>=0)if(f>>>0<=1073741823)if(f>>>0<=536870911)if(f>>>0<=268435455)if(f>>>0<=134217727)if(f>>>0<=67108863)if(f>>>0<=33554431)if(f>>>0<=16777215)if(f>>>0<=8388607)if(f>>>0>4194303){H=9;k=59}else{if(f>>>0>2097151){H=10;k=59;break}if(f>>>0>1048575){H=11;k=59;break}if(f>>>0>524287){H=12;k=59;break}if(f>>>0>262143){H=13;k=59;break}if(f>>>0>131071){p=14;o=f<<15;n=r+-15|0;q=s;k=(s|0)!=0?s:4}else{if(f>>>0<65536){J=1;k=127;break b}p=15;o=f<<16;n=r+-16|0;q=(s|0)!=0?s:1;k=12}G=p<>>0>>0){if((lb(a,32-y|0)|0)==-1){J=1;k=127;break}o=32;f=kb(a)|0}else{o=y;f=B}E=o-x|0;F=f<>>(32-x|0))+G|0;C=z;D=w}s=(t|0)==(v|0)&u?A+2|0:A;o=(s+2|0)>>>1;n=D?1:C;c[M+(t<<2)>>2]=(s&1|0)==0?o:0-o|0;t=t+1|0;if(t>>>0>=I>>>0){l=E;m=F;break a}else{p=E;f=F;s=((o|0)>(3<>>0<6&1)+n|0}}if((k|0)==127){i=O;return J|0}}else{l=p;m=f}while(0);if(I>>>0>>0){do if(l>>>0<9)if((lb(a,32-l|0)|0)==-1){C=1;i=O;return C|0}else{l=32;m=kb(a)|0;break}while(0);k=m>>>23;c:do if((g|0)==4)if((m|0)>=0)if((I|0)!=3)if(m>>>0<=1073741823)if((I|0)==2)k=34;else k=m>>>0>536870911?35:51;else k=18;else k=17;else k=1;else{do switch(I|0){case 8:{k=d[1056+(m>>>26)>>0]|0;break}case 9:{k=d[1120+(m>>>26)>>0]|0;break}case 2:{k=d[736+(m>>>26)>>0]|0;break}case 1:{if(m>>>0>268435455)k=d[672+(m>>>27)>>0]|0;else k=d[704+k>>0]|0;break}case 13:{k=d[1248+(m>>>29)>>0]|0;break}case 14:{k=d[1256+(m>>>30)>>0]|0;break}case 3:{k=d[800+(m>>>26)>>0]|0;break}case 4:{k=d[864+(m>>>27)>>0]|0;break}case 5:{k=d[896+(m>>>27)>>0]|0;break}case 10:{k=d[1184+(m>>>27)>>0]|0;break}case 6:{k=d[928+(m>>>26)>>0]|0;break}case 7:{k=d[992+(m>>>26)>>0]|0;break}case 11:{k=d[1216+(m>>>28)>>0]|0;break}case 12:{k=d[1232+(m>>>28)>>0]|0;break}default:{k=m>>31&16|1;break c}}while(0);if(!k){C=1;i=O;return C|0}}while(0);n=k&15;l=l-n|0;m=m<>>4&15}else n=0;p=I+-1|0;f=(p|0)==0;if(f){c[b+(n<<2)>>2]=c[M+(p<<2)>>2];K=l;h=1<>2]=1;L=l;j=0}else{if(l>>>0<11){if((lb(a,32-l|0)|0)==-1){J=1;k=127;break}l=32;k=kb(a)|0}switch(n|0){case 4:{m=d[648+(k>>>29)>>0]|0;break}case 5:{m=d[656+(k>>>29)>>0]|0;break}case 6:{m=d[664+(k>>>29)>>0]|0;break}case 1:{m=d[624+(k>>>31)>>0]|0;break}case 2:{m=d[632+(k>>>30)>>0]|0;break}case 3:{m=d[640+(k>>>30)>>0]|0;break}default:{do if(k>>>0<=536870911)if(k>>>0<=268435455)if(k>>>0<=134217727)if(k>>>0<=67108863)if(k>>>0<=33554431)if(k>>>0>16777215)m=184;else{if(k>>>0>8388607){m=201;break}if(k>>>0>4194303){m=218;break}m=k>>>0<2097152?0:235}else m=167;else m=150;else m=133;else m=116;else m=k>>>29<<4^115;while(0);if((m>>>4&15)>>>0>n>>>0){J=1;k=127;break d}}}if(!m){J=1;k=127;break}C=m&15;j=m>>>4&15;c[N+(o<<2)>>2]=j+1;L=l-C|0;k=k<>>0>=p>>>0){k=122;break}else{l=L;n=j}}if((k|0)==122){c[b+(j<<2)>>2]=c[M+(p<<2)>>2];h=1<>2]|0)+j|0;h=1<>2]=c[M+(k<<2)>>2];if(!k){K=L;break}else k=k+-1|0}}else if((k|0)==127){i=O;return J|0}}else{K=p;h=0}while(0);if(lb(a,32-K|0)|0){C=1;i=O;return C|0}C=h<<16|I<<4;i=O;return C|0}function sb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;a:do if((jb(a,1)|0)!=-1?(e=b+4|0,c[e>>2]=jb(a,2)|0,d=jb(a,5)|0,c[b>>2]=d,(d+-2|0)>>>0>=3):0){switch(d|0){case 6:case 9:case 10:case 11:case 12:{if(c[e>>2]|0){d=1;break a}break}case 5:case 7:case 8:{if(!(c[e>>2]|0)){d=1;break a}switch(d|0){case 6:case 9:case 10:case 11:case 12:{d=1;break a}default:{}}break}default:{}}d=0}else d=1;while(0);i=f;return d|0}function tb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;if(!d){i=o;return}m=b+-1|0;j=1-b|0;k=~b;g=0;h=0;l=0;while(1){f=(g|0)!=0;if(f)c[a+(h*216|0)+200>>2]=a+((h+-1|0)*216|0);else c[a+(h*216|0)+200>>2]=0;e=(l|0)!=0;if(e){c[a+(h*216|0)+204>>2]=a+((h-b|0)*216|0);if(g>>>0>>0)c[a+(h*216|0)+208>>2]=a+((j+h|0)*216|0);else n=10}else{c[a+(h*216|0)+204>>2]=0;n=10}if((n|0)==10){n=0;c[a+(h*216|0)+208>>2]=0}if(e&f)c[a+(h*216|0)+212>>2]=a+((h+k|0)*216|0);else c[a+(h*216|0)+212>>2]=0;e=g+1|0;f=(e|0)==(b|0);h=h+1|0;if((h|0)==(d|0))break;else{g=f?0:e;l=(f&1)+l|0}}i=o;return}function ub(a,b){a=a|0;b=b|0;var d=0;d=i;switch(b|0){case 1:{a=c[a+204>>2]|0;break}case 3:{a=c[a+212>>2]|0;break}case 4:break;case 2:{a=c[a+208>>2]|0;break}case 0:{a=c[a+200>>2]|0;break}default:a=0}i=d;return a|0}function vb(a){a=a|0;return 3152+(a<<3)|0}function wb(a){a=a|0;return 2960+(a<<3)|0}function xb(a){a=a|0;return 2768+(a<<3)|0}function yb(a){a=a|0;return 2576+(a<<3)|0}function zb(a,b){a=a|0;b=b|0;var d=0;d=i;if(!b){i=d;return 0}else{i=d;return (c[a+4>>2]|0)==(c[b+4>>2]|0)|0}return 0}function Ab(a){a=a|0;var b=0;b=i;id(a,0,3388);c[a+8>>2]=32;c[a+4>>2]=256;c[a+1332>>2]=1;i=b;return}function Bb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;f=c[b+8>>2]|0;g=a+(f<<2)+20|0;e=c[g>>2]|0;do if(!e){d=fd(92)|0;c[g>>2]=d;if(!d){d=65535;i=h;return d|0}}else{d=a+8|0;if((f|0)!=(c[d>>2]|0)){gd(c[e+40>>2]|0);c[(c[g>>2]|0)+40>>2]=0;gd(c[(c[g>>2]|0)+84>>2]|0);c[(c[g>>2]|0)+84>>2]=0;break}f=a+16|0;if(Ra(b,c[f>>2]|0)|0){gd(c[(c[g>>2]|0)+40>>2]|0);c[(c[g>>2]|0)+40>>2]=0;gd(c[(c[g>>2]|0)+84>>2]|0);c[(c[g>>2]|0)+84>>2]=0;c[d>>2]=33;c[a+4>>2]=257;c[f>>2]=0;c[a+12>>2]=0;break}d=b+40|0;gd(c[d>>2]|0);c[d>>2]=0;d=b+84|0;gd(c[d>>2]|0);c[d>>2]=0;d=0;i=h;return d|0}while(0);f=(c[g>>2]|0)+0|0;d=b+0|0;e=f+92|0;do{c[f>>2]=c[d>>2];f=f+4|0;d=d+4|0}while((f|0)<(e|0));d=0;i=h;return d|0}function Cb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;f=c[b>>2]|0;g=a+(f<<2)+148|0;d=c[g>>2]|0;do if(!d){d=fd(72)|0;c[g>>2]=d;if(!d){d=65535;i=h;return d|0}}else{e=a+4|0;if((f|0)!=(c[e>>2]|0)){gd(c[d+20>>2]|0);c[(c[g>>2]|0)+20>>2]=0;gd(c[(c[g>>2]|0)+24>>2]|0);c[(c[g>>2]|0)+24>>2]=0;gd(c[(c[g>>2]|0)+28>>2]|0);c[(c[g>>2]|0)+28>>2]=0;gd(c[(c[g>>2]|0)+44>>2]|0);c[(c[g>>2]|0)+44>>2]=0;break}if((c[b+4>>2]|0)!=(c[a+8>>2]|0)){c[e>>2]=257;d=c[g>>2]|0}gd(c[d+20>>2]|0);c[(c[g>>2]|0)+20>>2]=0;gd(c[(c[g>>2]|0)+24>>2]|0);c[(c[g>>2]|0)+24>>2]=0;gd(c[(c[g>>2]|0)+28>>2]|0);c[(c[g>>2]|0)+28>>2]=0;gd(c[(c[g>>2]|0)+44>>2]|0);c[(c[g>>2]|0)+44>>2]=0}while(0);f=(c[g>>2]|0)+0|0;d=b+0|0;e=f+72|0;do{c[f>>2]=c[d>>2];f=f+4|0;d=d+4|0}while((f|0)<(e|0));d=0;i=h;return d|0}function Db(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;o=a+(b<<2)+148|0;f=c[o>>2]|0;if(!f){o=1;i=q;return o|0}n=c[f+4>>2]|0;g=c[a+(n<<2)+20>>2]|0;if(!g){o=1;i=q;return o|0}l=c[g+52>>2]|0;m=Z(c[g+56>>2]|0,l)|0;h=c[f+12>>2]|0;a:do if(h>>>0>1){g=c[f+16>>2]|0;if((g|0)==2){k=c[f+24>>2]|0;j=c[f+28>>2]|0;h=h+-1|0;e=0;while(1){f=c[k+(e<<2)>>2]|0;g=c[j+(e<<2)>>2]|0;if(!(f>>>0<=g>>>0&g>>>0>>0)){e=1;g=33;break}e=e+1|0;if(((f>>>0)%(l>>>0)|0)>>>0>((g>>>0)%(l>>>0)|0)>>>0){e=1;g=33;break}if(e>>>0>=h>>>0)break a}if((g|0)==33){i=q;return e|0}}else if(!g){g=c[f+20>>2]|0;f=0;while(1){if((c[g+(f<<2)>>2]|0)>>>0>m>>>0){e=1;break}f=f+1|0;if(f>>>0>=h>>>0)break a}i=q;return e|0}else{if((g+-3|0)>>>0<3){if((c[f+36>>2]|0)>>>0>m>>>0)e=1;else break;i=q;return e|0}if((g|0)!=6)break;if((c[f+40>>2]|0)>>>0>>0)e=1;else break;i=q;return e|0}}while(0);f=a+4|0;g=c[f>>2]|0;do if((g|0)!=256){e=a+3380|0;if(!(c[e>>2]|0)){if((g|0)==(b|0))break;g=a+8|0;if((n|0)==(c[g>>2]|0)){c[f>>2]=b;c[a+12>>2]=c[o>>2];break}if(!d){o=1;i=q;return o|0}else{c[f>>2]=b;o=c[o>>2]|0;c[a+12>>2]=o;o=c[o+4>>2]|0;c[g>>2]=o;o=c[a+(o<<2)+20>>2]|0;c[a+16>>2]=o;n=c[o+52>>2]|0;o=c[o+56>>2]|0;c[a+1176>>2]=Z(o,n)|0;c[a+1340>>2]=n;c[a+1344>>2]=o;c[e>>2]=1;break}}c[e>>2]=0;e=a+1212|0;gd(c[e>>2]|0);c[e>>2]=0;f=a+1172|0;gd(c[f>>2]|0);c[f>>2]=0;g=a+1176|0;c[e>>2]=fd((c[g>>2]|0)*216|0)|0;o=fd(c[g>>2]<<2)|0;c[f>>2]=o;f=c[e>>2]|0;if((f|0)==0|(o|0)==0){o=65535;i=q;return o|0}id(f,0,(c[g>>2]|0)*216|0);f=a+16|0;tb(c[e>>2]|0,c[(c[f>>2]|0)+52>>2]|0,c[g>>2]|0);f=c[f>>2]|0;do if((c[a+1216>>2]|0)==0?(c[f+16>>2]|0)!=2:0){if(((c[f+80>>2]|0)!=0?(p=c[f+84>>2]|0,(c[p+920>>2]|0)!=0):0)?(c[p+944>>2]|0)==0:0){e=1;break}e=0}else e=1;while(0);o=Z(c[f+56>>2]|0,c[f+52>>2]|0)|0;e=lc(a+1220|0,o,c[f+88>>2]|0,c[f+44>>2]|0,c[f+12>>2]|0,e)|0;if(e){o=e;i=q;return o|0}}else{c[f>>2]=b;o=c[o>>2]|0;c[a+12>>2]=o;o=c[o+4>>2]|0;c[a+8>>2]=o;o=c[a+(o<<2)+20>>2]|0;c[a+16>>2]=o;n=c[o+52>>2]|0;o=c[o+56>>2]|0;c[a+1176>>2]=Z(o,n)|0;c[a+1340>>2]=n;c[a+1344>>2]=o;c[a+3380>>2]=1}while(0);o=0;i=q;return o|0}function Eb(a){a=a|0;var b=0,d=0,e=0;e=i;c[a+1196>>2]=0;c[a+1192>>2]=0;d=c[a+1176>>2]|0;if(!d){i=e;return}a=c[a+1212>>2]|0;b=0;do{c[a+(b*216|0)+4>>2]=0;c[a+(b*216|0)+196>>2]=0;b=b+1|0}while(b>>>0>>0);i=e;return}function Fb(a){a=a|0;return (c[a+1188>>2]|0)==0|0}function Gb(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;if(!(c[a+1404>>2]|0)){if((c[a+1196>>2]|0)==(c[a+1176>>2]|0)){a=1;i=f;return a|0}}else{e=c[a+1176>>2]|0;if(!e){a=1;i=f;return a|0}a=c[a+1212>>2]|0;b=0;d=0;do{d=((c[a+(b*216|0)+196>>2]|0)!=0&1)+d|0;b=b+1|0}while(b>>>0>>0);if((d|0)==(e|0)){a=1;i=f;return a|0}}a=0;i=f;return a|0}function Hb(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;e=c[a+16>>2]|0;Kb(c[a+1172>>2]|0,c[a+12>>2]|0,b,c[e+52>>2]|0,c[e+56>>2]|0);i=d;return}function Ib(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;i=i+32|0;g=t+24|0;j=t+20|0;k=t+16|0;n=t+12|0;r=t+8|0;q=t;c[e>>2]=0;switch(c[b>>2]|0){case 5:case 1:{s=d+1300|0;h=d+1332|0;if(c[h>>2]|0){c[e>>2]=1;c[h>>2]=0}h=Ua(a,g)|0;if(h){o=h;i=t;return o|0}l=c[d+(c[g>>2]<<2)+148>>2]|0;if(!l){o=65520;i=t;return o|0}h=c[l+4>>2]|0;m=c[d+(h<<2)+20>>2]|0;if(!m){o=65520;i=t;return o|0}g=c[d+8>>2]|0;if(!((g|0)==32|(h|0)==(g|0))?(c[b>>2]|0)!=5:0){o=65520;i=t;return o|0}g=c[d+1304>>2]|0;h=c[b+4>>2]|0;if((g|0)!=(h|0)?(g|0)==0|(h|0)==0:0)c[e>>2]=1;h=(c[b>>2]|0)==5;if((c[s>>2]|0)==5){if(!h)f=16}else if(h)f=16;if((f|0)==16)c[e>>2]=1;g=m+12|0;if(Va(a,c[g>>2]|0,j)|0){o=1;i=t;return o|0}f=d+1308|0;h=c[j>>2]|0;if((c[f>>2]|0)!=(h|0)){c[f>>2]=h;c[e>>2]=1}if((c[b>>2]|0)==5){if(Wa(a,c[g>>2]|0,5,k)|0){o=1;i=t;return o|0}if((c[s>>2]|0)==5){h=d+1312|0;f=c[h>>2]|0;g=c[k>>2]|0;if((f|0)==(g|0))g=f;else c[e>>2]=1}else{g=c[k>>2]|0;h=d+1312|0}c[h>>2]=g}g=c[m+16>>2]|0;if((g|0)==1){if(!(c[m+24>>2]|0)){h=l+8|0;g=Za(a,m,c[b>>2]|0,c[h>>2]|0,q)|0;if(g){o=g;i=t;return o|0}f=d+1324|0;g=c[q>>2]|0;if((c[f>>2]|0)!=(g|0)){c[f>>2]=g;c[e>>2]=1}if((c[h>>2]|0)!=0?(p=d+1328|0,o=c[q+4>>2]|0,(c[p>>2]|0)!=(o|0)):0){c[p>>2]=o;c[e>>2]=1}}}else if(!g){if(Xa(a,m,c[b>>2]|0,n)|0){o=1;i=t;return o|0}f=d+1316|0;g=c[n>>2]|0;if((c[f>>2]|0)!=(g|0)){c[f>>2]=g;c[e>>2]=1}if(c[l+8>>2]|0){f=Ya(a,m,c[b>>2]|0,r)|0;if(f){o=f;i=t;return o|0}g=d+1320|0;f=c[r>>2]|0;if((c[g>>2]|0)!=(f|0)){c[g>>2]=f;c[e>>2]=1}}}n=b;a=c[n+4>>2]|0;o=s;c[o>>2]=c[n>>2];c[o+4>>2]=a;o=0;i=t;return o|0}case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 16:case 17:case 18:{c[e>>2]=1;o=0;i=t;return o|0}default:{o=0;i=t;return o|0}}return 0}function Jb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;n=i;l=0;a:while(1){b=c[a+(l<<2)+148>>2]|0;b:do if((b|0)!=0?(k=c[a+(c[b+4>>2]<<2)+20>>2]|0,(k|0)!=0):0){j=c[k+52>>2]|0;m=Z(c[k+56>>2]|0,j)|0;f=c[b+12>>2]|0;if(f>>>0<=1){b=0;d=18;break a}d=c[b+16>>2]|0;if((d|0)==2){h=c[b+24>>2]|0;g=c[b+28>>2]|0;f=f+-1|0;e=0;while(1){b=c[h+(e<<2)>>2]|0;d=c[g+(e<<2)>>2]|0;if(!(b>>>0<=d>>>0&d>>>0>>0))break b;e=e+1|0;if(((b>>>0)%(j>>>0)|0)>>>0>((d>>>0)%(j>>>0)|0)>>>0)break b;if(e>>>0>=f>>>0){b=0;d=18;break a}}}else if(d){if((d+-3|0)>>>0<3)if((c[b+36>>2]|0)>>>0>m>>>0)break;else{b=0;d=18;break a}if((d|0)!=6){b=0;d=18;break a}if((c[b+40>>2]|0)>>>0>>0)break;else{b=0;d=18;break a}}else{d=c[b+20>>2]|0;b=0;while(1){if((c[d+(b<<2)>>2]|0)>>>0>m>>>0)break b;b=b+1|0;if(b>>>0>=f>>>0){b=0;d=18;break a}}}}while(0);l=l+1|0;if(l>>>0>=256){b=1;d=18;break}}if((d|0)==18){i=n;return b|0}return 0}function Kb(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=i;t=Z(f,e)|0;o=c[b+12>>2]|0;if((o|0)==1){id(a,0,t<<2);i=v;return}k=c[b+16>>2]|0;if((k+-3|0)>>>0<3){d=Z(c[b+36>>2]|0,d)|0;d=d>>>0>>0?d:t;if((k&-2|0)==4){n=(c[b+32>>2]|0)==0?d:t-d|0;u=d}else{n=0;u=d}}else{n=0;u=0}switch(k|0){case 0:{l=c[b+20>>2]|0;if(!t){i=v;return}else{h=0;j=0}while(1){while(1)if(h>>>0>>0)break;else h=0;b=l+(h<<2)|0;d=c[b>>2]|0;a:do if(!d)d=0;else{k=0;do{g=k+j|0;if(g>>>0>=t>>>0)break a;c[a+(g<<2)>>2]=h;k=k+1|0;d=c[b>>2]|0}while(k>>>0>>0)}while(0);j=d+j|0;if(j>>>0>=t>>>0)break;else h=h+1|0}i=v;return}case 4:{h=c[b+32>>2]|0;if(!t){i=v;return}d=1-h|0;g=0;do{c[a+(g<<2)>>2]=g>>>0>>0?h:d;g=g+1|0}while((g|0)!=(t|0));i=v;return}case 1:{if(!t){i=v;return}else h=0;do{c[a+(h<<2)>>2]=((((Z((h>>>0)/(e>>>0)|0,o)|0)>>>1)+((h>>>0)%(e>>>0)|0)|0)>>>0)%(o>>>0)|0;h=h+1|0}while((h|0)!=(t|0));i=v;return}case 2:{n=c[b+24>>2]|0;m=c[b+28>>2]|0;h=o+-1|0;if(t){d=0;do{c[a+(d<<2)>>2]=h;d=d+1|0}while((d|0)!=(t|0))}if(!h){i=v;return}g=o+-2|0;while(1){j=c[n+(g<<2)>>2]|0;d=(j>>>0)/(e>>>0)|0;j=(j>>>0)%(e>>>0)|0;h=c[m+(g<<2)>>2]|0;l=(h>>>0)/(e>>>0)|0;h=(h>>>0)%(e>>>0)|0;b:do if(d>>>0<=l>>>0){if(j>>>0>h>>>0)while(1){d=d+1|0;if(d>>>0>l>>>0)break b}do{k=Z(d,e)|0;b=j;do{c[a+(b+k<<2)>>2]=g;b=b+1|0}while(b>>>0<=h>>>0);d=d+1|0}while(d>>>0<=l>>>0)}while(0);if(!g)break;else g=g+-1|0}i=v;return}case 5:{d=c[b+32>>2]|0;if(!e){i=v;return}k=1-d|0;if(!f){i=v;return}else{g=0;j=0}while(1){h=0;b=j;while(1){m=a+((Z(h,e)|0)+g<<2)|0;c[m>>2]=b>>>0>>0?d:k;h=h+1|0;if((h|0)==(f|0))break;else b=b+1|0}g=g+1|0;if((g|0)==(e|0))break;else j=j+f|0}i=v;return}case 3:{m=c[b+32>>2]|0;if(t){d=0;do{c[a+(d<<2)>>2]=1;d=d+1|0}while((d|0)!=(t|0))}l=(e-m|0)>>>1;n=(f-m|0)>>>1;if(!u){i=v;return}t=m<<1;r=t+-1|0;s=e+-1|0;t=1-t|0;q=f+-1|0;o=n;p=0;g=l;f=l;k=n;b=l;j=m+-1|0;d=n;while(1){n=a+((Z(d,e)|0)+b<<2)|0;l=(c[n>>2]|0)==1;h=l&1;if(l)c[n>>2]=0;do if(!((j|0)==-1&(b|0)==(g|0))){if((j|0)==1&(b|0)==(f|0)){b=f+1|0;b=(b|0)<(s|0)?b:s;n=o;l=g;f=b;j=0;m=t;break}if((m|0)==-1&(d|0)==(k|0)){d=k+-1|0;d=(d|0)>0?d:0;n=o;l=g;k=d;j=t;m=0;break}if((m|0)==1&(d|0)==(o|0)){d=o+1|0;d=(d|0)<(q|0)?d:q;n=d;l=g;j=r;m=0;break}else{n=o;l=g;b=b+j|0;d=d+m|0;break}}else{b=g+-1|0;b=(b|0)>0?b:0;n=o;l=b;j=0;m=r}while(0);p=h+p|0;if(p>>>0>=u>>>0)break;else{o=n;g=l}}i=v;return}default:{if(!t){i=v;return}g=c[b+44>>2]|0;h=0;do{c[a+(h<<2)>>2]=c[g+(h<<2)>>2];h=h+1|0}while((h|0)!=(t|0));i=v;return}}}function Lb(){return 3472}function Mb(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0;k=i;i=i+80|0;h=k+32|0;j=k;Nb(d,h,j,e);if((cb(c[a>>2]|0)|0)==1){e=Ob(a,g,b+328|0,h,j,f)|0;if(e){i=k;return e|0}}else{e=Pb(a,g,b,h,j,f)|0;if(e){i=k;return e|0}}e=Qb(a,g+256|0,b+1352|0,h+21|0,j+16|0,c[b+140>>2]|0,f)|0;if(e){i=k;return e|0}if((c[a+196>>2]|0)>>>0>1){e=0;i=k;return e|0}sc(d,g);e=0;i=k;return e|0}function Nb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=i;if(!f){i=s;return}p=c[b+4>>2]|0;q=Z(c[b+8>>2]|0,p)|0;n=(f>>>0)/(p>>>0)|0;g=Z(n,p)|0;o=f-g|0;k=p<<4;h=c[b>>2]|0;j=(o<<4)+(Z(p<<8,n)|0)|0;r=(n|0)!=0;if(r){m=j-(k|1)|0;a[d>>0]=a[h+m>>0]|0;a[d+1>>0]=a[h+(m+1)>>0]|0;a[d+2>>0]=a[h+(m+2)>>0]|0;a[d+3>>0]=a[h+(m+3)>>0]|0;a[d+4>>0]=a[h+(m+4)>>0]|0;a[d+5>>0]=a[h+(m+5)>>0]|0;a[d+6>>0]=a[h+(m+6)>>0]|0;a[d+7>>0]=a[h+(m+7)>>0]|0;a[d+8>>0]=a[h+(m+8)>>0]|0;a[d+9>>0]=a[h+(m+9)>>0]|0;a[d+10>>0]=a[h+(m+10)>>0]|0;a[d+11>>0]=a[h+(m+11)>>0]|0;a[d+12>>0]=a[h+(m+12)>>0]|0;a[d+13>>0]=a[h+(m+13)>>0]|0;a[d+14>>0]=a[h+(m+14)>>0]|0;a[d+15>>0]=a[h+(m+15)>>0]|0;a[d+16>>0]=a[h+(m+16)>>0]|0;a[d+17>>0]=a[h+(m+17)>>0]|0;a[d+18>>0]=a[h+(m+18)>>0]|0;a[d+19>>0]=a[h+(m+19)>>0]|0;a[d+20>>0]=a[h+(m+20)>>0]|0;m=d+21|0}else m=d;l=(g|0)!=(f|0);if(l){j=j+-1|0;a[e>>0]=a[h+j>>0]|0;j=j+k|0;a[e+1>>0]=a[h+j>>0]|0;j=j+k|0;a[e+2>>0]=a[h+j>>0]|0;j=j+k|0;a[e+3>>0]=a[h+j>>0]|0;j=j+k|0;a[e+4>>0]=a[h+j>>0]|0;j=j+k|0;a[e+5>>0]=a[h+j>>0]|0;j=j+k|0;a[e+6>>0]=a[h+j>>0]|0;j=j+k|0;a[e+7>>0]=a[h+j>>0]|0;j=j+k|0;a[e+8>>0]=a[h+j>>0]|0;j=j+k|0;a[e+9>>0]=a[h+j>>0]|0;j=j+k|0;a[e+10>>0]=a[h+j>>0]|0;j=j+k|0;a[e+11>>0]=a[h+j>>0]|0;j=j+k|0;a[e+12>>0]=a[h+j>>0]|0;j=j+k|0;a[e+13>>0]=a[h+j>>0]|0;j=j+k|0;a[e+14>>0]=a[h+j>>0]|0;a[e+15>>0]=a[h+(j+k)>>0]|0;e=e+16|0}d=p<<3&2147483640;f=c[b>>2]|0;g=(Z(n<<3,d)|0)+(q<<8)+(o<<3)|0;if(r){b=g-(d|1)|0;a[m>>0]=a[f+b>>0]|0;a[m+1>>0]=a[f+(b+1)>>0]|0;a[m+2>>0]=a[f+(b+2)>>0]|0;a[m+3>>0]=a[f+(b+3)>>0]|0;a[m+4>>0]=a[f+(b+4)>>0]|0;a[m+5>>0]=a[f+(b+5)>>0]|0;a[m+6>>0]=a[f+(b+6)>>0]|0;a[m+7>>0]=a[f+(b+7)>>0]|0;a[m+8>>0]=a[f+(b+8)>>0]|0;b=b+(q<<6)|0;a[m+9>>0]=a[f+b>>0]|0;a[m+10>>0]=a[f+(b+1)>>0]|0;a[m+11>>0]=a[f+(b+2)>>0]|0;a[m+12>>0]=a[f+(b+3)>>0]|0;a[m+13>>0]=a[f+(b+4)>>0]|0;a[m+14>>0]=a[f+(b+5)>>0]|0;a[m+15>>0]=a[f+(b+6)>>0]|0;a[m+16>>0]=a[f+(b+7)>>0]|0;a[m+17>>0]=a[f+(b+8)>>0]|0}if(!l){i=s;return}m=g+-1|0;a[e>>0]=a[f+m>>0]|0;m=m+d|0;a[e+1>>0]=a[f+m>>0]|0;m=m+d|0;a[e+2>>0]=a[f+m>>0]|0;m=m+d|0;a[e+3>>0]=a[f+m>>0]|0;m=m+d|0;a[e+4>>0]=a[f+m>>0]|0;m=m+d|0;a[e+5>>0]=a[f+m>>0]|0;m=m+d|0;a[e+6>>0]=a[f+m>>0]|0;m=m+d|0;a[e+7>>0]=a[f+m>>0]|0;m=m+(d+((q<<6)-(p<<6)))|0;a[e+8>>0]=a[f+m>>0]|0;m=m+d|0;a[e+9>>0]=a[f+m>>0]|0;m=m+d|0;a[e+10>>0]=a[f+m>>0]|0;m=m+d|0;a[e+11>>0]=a[f+m>>0]|0;m=m+d|0;a[e+12>>0]=a[f+m>>0]|0;m=m+d|0;a[e+13>>0]=a[f+m>>0]|0;m=m+d|0;a[e+14>>0]=a[f+m>>0]|0;a[e+15>>0]=a[f+(m+d)>>0]|0;i=s;return}function Ob(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;z=i;k=b+200|0;l=zb(b,c[k>>2]|0)|0;o=(j|0)!=0;if((l|0)!=0&o){n=(cb(c[c[k>>2]>>2]|0)|0)==2;n=n?0:l}else n=l;j=b+204|0;l=zb(b,c[j>>2]|0)|0;if((l|0)!=0&o){p=(cb(c[c[j>>2]>>2]|0)|0)==2;p=p?0:l}else p=l;j=b+212|0;l=zb(b,c[j>>2]|0)|0;if((l|0)!=0&o){r=(cb(c[c[j>>2]>>2]|0)|0)==2;l=r?0:l}j=fb(c[b>>2]|0)|0;if(!j){if(!p){r=1;i=z;return r|0}b=g+1|0;m=g+2|0;s=g+3|0;t=g+4|0;u=g+5|0;v=g+6|0;w=g+7|0;x=g+8|0;y=g+9|0;h=g+10|0;l=g+11|0;j=g+12|0;k=g+13|0;q=g+14|0;r=g+15|0;p=g+16|0;o=e;n=0;while(1){a[o>>0]=a[b>>0]|0;a[o+1>>0]=a[m>>0]|0;a[o+2>>0]=a[s>>0]|0;a[o+3>>0]=a[t>>0]|0;a[o+4>>0]=a[u>>0]|0;a[o+5>>0]=a[v>>0]|0;a[o+6>>0]=a[w>>0]|0;a[o+7>>0]=a[x>>0]|0;a[o+8>>0]=a[y>>0]|0;a[o+9>>0]=a[h>>0]|0;a[o+10>>0]=a[l>>0]|0;a[o+11>>0]=a[j>>0]|0;a[o+12>>0]=a[k>>0]|0;a[o+13>>0]=a[q>>0]|0;a[o+14>>0]=a[r>>0]|0;a[o+15>>0]=a[p>>0]|0;n=n+1|0;if((n|0)==16)break;else o=o+16|0}}else if((j|0)==2){l=g+1|0;k=(n|0)!=0;j=(p|0)!=0;do if(!(k&j)){if(k){k=((d[h>>0]|0)+8+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)+(d[h+4>>0]|0)+(d[h+5>>0]|0)+(d[h+6>>0]|0)+(d[h+7>>0]|0)+(d[h+8>>0]|0)+(d[h+9>>0]|0)+(d[h+10>>0]|0)+(d[h+11>>0]|0)+(d[h+12>>0]|0)+(d[h+13>>0]|0)+(d[h+14>>0]|0)+(d[h+15>>0]|0)|0)>>>4;break}if(j)k=((d[l>>0]|0)+8+(d[g+2>>0]|0)+(d[g+3>>0]|0)+(d[g+4>>0]|0)+(d[g+5>>0]|0)+(d[g+6>>0]|0)+(d[g+7>>0]|0)+(d[g+8>>0]|0)+(d[g+9>>0]|0)+(d[g+10>>0]|0)+(d[g+11>>0]|0)+(d[g+12>>0]|0)+(d[g+13>>0]|0)+(d[g+14>>0]|0)+(d[g+15>>0]|0)+(d[g+16>>0]|0)|0)>>>4;else k=128}else{j=0;k=0;do{r=j;j=j+1|0;k=(d[g+j>>0]|0)+k+(d[h+r>>0]|0)|0}while((j|0)!=16);k=(k+16|0)>>>5}while(0);nd(e|0,k&255|0,256)|0}else if((j|0)==1)if(!n){r=1;i=z;return r|0}else{k=e;j=0;while(1){r=h+j|0;a[k>>0]=a[r>>0]|0;a[k+1>>0]=a[r>>0]|0;a[k+2>>0]=a[r>>0]|0;a[k+3>>0]=a[r>>0]|0;a[k+4>>0]=a[r>>0]|0;a[k+5>>0]=a[r>>0]|0;a[k+6>>0]=a[r>>0]|0;a[k+7>>0]=a[r>>0]|0;a[k+8>>0]=a[r>>0]|0;a[k+9>>0]=a[r>>0]|0;a[k+10>>0]=a[r>>0]|0;a[k+11>>0]=a[r>>0]|0;a[k+12>>0]=a[r>>0]|0;a[k+13>>0]=a[r>>0]|0;a[k+14>>0]=a[r>>0]|0;a[k+15>>0]=a[r>>0]|0;j=j+1|0;if((j|0)==16)break;else k=k+16|0}}else{if(!((n|0)!=0&(p|0)!=0&(l|0)!=0)){r=1;i=z;return r|0}j=d[g+16>>0]|0;m=d[h+15>>0]|0;o=d[g>>0]|0;p=(((d[g+9>>0]|0)-(d[g+7>>0]|0)+((d[g+10>>0]|0)-(d[g+6>>0]|0)<<1)+(((d[g+11>>0]|0)-(d[g+5>>0]|0)|0)*3|0)+((d[g+12>>0]|0)-(d[g+4>>0]|0)<<2)+(((d[g+13>>0]|0)-(d[g+3>>0]|0)|0)*5|0)+(((d[g+14>>0]|0)-(d[g+2>>0]|0)|0)*6|0)+(((d[g+15>>0]|0)-(d[g+1>>0]|0)|0)*7|0)+(j-o<<3)|0)*5|0)+32>>6;o=(((d[h+8>>0]|0)-(d[h+6>>0]|0)+(m-o<<3)+((d[h+9>>0]|0)-(d[h+5>>0]|0)<<1)+(((d[h+10>>0]|0)-(d[h+4>>0]|0)|0)*3|0)+((d[h+11>>0]|0)-(d[h+3>>0]|0)<<2)+(((d[h+12>>0]|0)-(d[h+2>>0]|0)|0)*5|0)+(((d[h+13>>0]|0)-(d[h+1>>0]|0)|0)*6|0)+(((d[h+14>>0]|0)-(d[h>>0]|0)|0)*7|0)|0)*5|0)+32>>6;j=(m+j<<4)+16|0;m=0;do{k=j+(Z(m+-7|0,o)|0)|0;n=m<<4;b=0;do{l=k+(Z(b+-7|0,p)|0)>>5;if((l|0)<0)l=0;else l=(l|0)>255?-1:l&255;a[e+(b+n)>>0]=l;b=b+1|0}while((b|0)!=16);m=m+1|0}while((m|0)!=16)}Rb(e,f,0);Rb(e,f+64|0,1);Rb(e,f+128|0,2);Rb(e,f+192|0,3);Rb(e,f+256|0,4);Rb(e,f+320|0,5);Rb(e,f+384|0,6);Rb(e,f+448|0,7);Rb(e,f+512|0,8);Rb(e,f+576|0,9);Rb(e,f+640|0,10);Rb(e,f+704|0,11);Rb(e,f+768|0,12);Rb(e,f+832|0,13);Rb(e,f+896|0,14);Rb(e,f+960|0,15);r=0;i=z;return r|0}function Pb(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0;N=i;M=(j|0)!=0;L=0;a:while(1){l=vb(L)|0;n=c[l+4>>2]|0;l=ub(b,c[l>>2]|0)|0;j=zb(b,l)|0;if((j|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;j=E?0:j}o=wb(L)|0;m=c[o+4>>2]|0;o=ub(b,c[o>>2]|0)|0;k=zb(b,o)|0;if((k|0)!=0&M){E=(cb(c[o>>2]|0)|0)==2;k=E?0:k}G=(j|0)!=0;H=(k|0)!=0;I=G&H;if(I){if(!(cb(c[l>>2]|0)|0))n=d[l+(n&255)+82>>0]|0;else n=2;if(!(cb(c[o>>2]|0)|0))j=d[o+(m&255)+82>>0]|0;else j=2;j=n>>>0>>0?n:j}else j=2;if(!(c[f+(L<<2)+12>>2]|0)){E=c[f+(L<<2)+76>>2]|0;j=(E>>>0>=j>>>0&1)+E|0}a[b+L+82>>0]=j;l=c[(xb(L)|0)>>2]|0;l=ub(b,l)|0;m=zb(b,l)|0;if((m|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;m=E?0:m}l=c[(yb(L)|0)>>2]|0;l=ub(b,l)|0;n=zb(b,l)|0;if((n|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;n=E?0:n}J=c[3344+(L<<2)>>2]|0;K=c[3408+(L<<2)>>2]|0;r=(1285>>>L&1|0)!=0;if(r){o=h+K|0;l=h+(K+1)|0;p=h+(K+2)|0;q=h+(K+3)|0}else{q=(K<<4)+J|0;o=e+(q+-1)|0;l=e+(q+15)|0;p=e+(q+31)|0;q=e+(q+47)|0}A=a[o>>0]|0;y=a[l>>0]|0;F=a[p>>0]|0;E=a[q>>0]|0;do if(!(51>>>L&1)){x=K+-1|0;w=(x<<4)+J|0;o=a[e+w>>0]|0;q=a[e+(w+1)>>0]|0;s=a[e+(w+2)>>0]|0;u=a[e+(w+3)>>0]|0;t=a[e+(w+4)>>0]|0;l=a[e+(w+5)>>0]|0;v=a[e+(w+6)>>0]|0;p=a[e+(w+7)>>0]|0;if(r){D=v;C=u;u=p;B=q;z=s;v=h+x|0;break}else{D=v;C=u;u=p;B=q;z=s;v=e+(w+-1)|0;break}}else{D=a[g+(J+7)>>0]|0;C=a[g+(J+4)>>0]|0;t=a[g+(J+5)>>0]|0;l=a[g+(J+6)>>0]|0;o=a[g+(J+1)>>0]|0;u=a[g+(J+8)>>0]|0;B=a[g+(J+2)>>0]|0;z=a[g+(J+3)>>0]|0;v=g+J|0}while(0);v=a[v>>0]|0;switch(j|0){case 4:{if(!(I&(n|0)!=0)){k=1;j=51;break a}j=o&255;o=v&255;q=A&255;s=j+2|0;D=(s+q+(o<<1)|0)>>>2;u=D&255;k=B&255;o=o+2|0;v=((j<<1)+k+o|0)>>>2&255;j=z&255;s=((k<<1)+j+s|0)>>>2&255;z=y&255;o=(z+(q<<1)+o|0)>>>2;t=o&255;A=F&255;B=(q+2+(z<<1)+A|0)>>>2;q=u;p=t;n=B&255;m=v;l=s;j=((C&255)+2+k+(j<<1)|0)>>>2&255;k=u;r=v;o=(z+2+(A<<1)+(E&255)|0)>>>2&255|B<<8&65280|D<<24|o<<16&16711680;break}case 6:{if(!(I&(n|0)!=0)){k=1;j=51;break a}l=v&255;s=A&255;u=s+1|0;r=(u+l|0)>>>1&255;C=y&255;v=((s<<1)+2+C+l|0)>>>2&255;u=(u+C|0)>>>1&255;D=F&255;s=s+2|0;y=(s+(C<<1)+D|0)>>>2;A=(C+1+D|0)>>>1;E=E&255;j=o&255;s=(s+j+(l<<1)|0)>>>2&255;k=B&255;q=r;p=u;n=A&255;m=s;l=(k+2+(j<<1)+l|0)>>>2&255;j=((z&255)+2+(k<<1)+j|0)>>>2&255;k=v;t=y&255;o=y<<24|A<<16&16711680|(D+1+E|0)>>>1&255|C+2+(D<<1)+E<<6&65280;break}case 2:{do if(!I){if(G){j=((A&255)+2+(y&255)+(F&255)+(E&255)|0)>>>2;break}if(H)j=((C&255)+2+(z&255)+(B&255)+(o&255)|0)>>>2;else j=128}else j=((A&255)+4+(y&255)+(F&255)+(E&255)+(C&255)+(z&255)+(B&255)+(o&255)|0)>>>3;while(0);o=Z(j&255,16843009)|0;n=o&255;t=o>>>8&255;u=o>>>16&255;v=o>>>24&255;q=n;p=n;m=t;l=u;j=v;k=t;r=u;s=v;break}case 0:{if(!k){k=1;j=51;break a}q=o;p=o;n=o;m=B;l=z;j=C;k=B;r=z;s=C;t=B;u=z;v=C;o=(z&255)<<16|(C&255)<<24|(B&255)<<8|o&255;break}case 1:{if(!G){k=1;j=51;break a}j=Z(A&255,16843009)|0;s=Z(y&255,16843009)|0;v=Z(F&255,16843009)|0;q=j&255;p=s&255;n=v&255;m=j>>>8&255;l=j>>>16&255;j=j>>>24&255;k=s>>>8&255;r=s>>>16&255;s=s>>>24&255;t=v>>>8&255;u=v>>>16&255;v=v>>>24&255;o=Z(E&255,16843009)|0;break}case 7:{if(!k){k=1;j=51;break a}A=(m|0)==0;n=o&255;p=B&255;z=z&255;m=(z+1+p|0)>>>1&255;o=C&255;u=o+1|0;v=(u+z|0)>>>1&255;B=(A?C:t)&255;u=(u+B|0)>>>1&255;j=z+2|0;y=o+2|0;z=(y+p+(z<<1)|0)>>>2;o=(j+(o<<1)+B|0)>>>2;E=(A?C:l)&255;y=(y+E+(B<<1)|0)>>>2;q=(p+1+n|0)>>>1&255;p=(j+n+(p<<1)|0)>>>2&255;n=m;l=v;j=u;k=z&255;r=o&255;s=y&255;t=v;v=(B+1+E|0)>>>1&255;o=y<<16&16711680|z&255|(B+2+((A?C:D)&255)+(E<<1)|0)>>>2<<24|o<<8&65280;break}case 3:{if(!k){k=1;j=51;break a}n=(m|0)==0;q=B&255;m=z&255;p=m+2|0;k=C&255;B=k+2|0;m=(B+q+(m<<1)|0)>>>2&255;v=(n?C:t)&255;k=(p+(k<<1)+v|0)>>>2&255;E=(n?C:l)&255;B=(B+E+(v<<1)|0)>>>2;t=B&255;A=(n?C:D)&255;D=(v+2+A+(E<<1)|0)>>>2;v=D&255;C=(n?C:u)&255;E=(E+2+C+(A<<1)|0)>>>2;q=(p+(o&255)+(q<<1)|0)>>>2&255;p=m;n=k;l=k;j=t;r=t;s=v;u=v;v=E&255;o=(A+2+(C*3|0)|0)>>>2<<24|B&255|D<<8&65280|E<<16&16711680;break}case 5:{if(!(I&(n|0)!=0)){k=1;j=51;break a}n=v&255;u=o&255;t=(u+1+n|0)>>>1&255;x=B&255;E=(x+2+(u<<1)+n|0)>>>2;B=A&255;A=u+2|0;o=(A+B+(n<<1)|0)>>>2;u=(x+1+u|0)>>>1&255;s=z&255;A=((x<<1)+s+A|0)>>>2;v=(s+1+x|0)>>>1&255;C=C&255;D=y&255;q=t;p=o&255;n=(D+2+(B<<1)+n|0)>>>2&255;m=u;l=v;j=(C+1+s|0)>>>1&255;k=E&255;r=A&255;s=(C+2+x+(s<<1)|0)>>>2&255;o=A<<24|(B+2+(F&255)+(D<<1)|0)>>>2&255|E<<16&16711680|o<<8&65280;break}default:{if(!G){k=1;j=51;break a}s=A&255;j=y&255;m=F&255;l=(j+1+m|0)>>>1&255;o=E&255;k=(j+2+(m<<1)+o|0)>>>2&255;r=(m+1+o|0)>>>1&255;t=(m+2+(o*3|0)|0)>>>2&255;q=(s+1+j|0)>>>1&255;p=l;n=r;m=(s+2+(j<<1)+m|0)>>>2&255;j=k;s=t;u=E;v=E;o=o<<8|o|o<<16|o<<24}}E=(K<<4)+J|0;c[e+E>>2]=(l&255)<<16|(j&255)<<24|(m&255)<<8|q&255;c[e+(E+16)>>2]=(r&255)<<16|(s&255)<<24|(k&255)<<8|p&255;c[e+(E+32)>>2]=(u&255)<<16|(v&255)<<24|(t&255)<<8|n&255;c[e+(E+48)>>2]=o;Rb(e,f+(L<<6)+328|0,L);L=L+1|0;if(L>>>0>=16){k=0;j=51;break}}if((j|0)==51){i=N;return k|0}return 0}function Qb(b,e,f,g,h,j,k){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;y=i;m=b+200|0;l=zb(b,c[m>>2]|0)|0;n=(k|0)!=0;if((l|0)!=0&n){o=(cb(c[c[m>>2]>>2]|0)|0)==2;l=o?0:l}m=b+204|0;k=zb(b,c[m>>2]|0)|0;if((k|0)!=0&n){o=(cb(c[c[m>>2]>>2]|0)|0)==2;o=o?0:k}else o=k;m=b+212|0;k=zb(b,c[m>>2]|0)|0;if((k|0)!=0&n){n=(cb(c[c[m>>2]>>2]|0)|0)==2;k=n?0:k}w=(l|0)!=0;x=(o|0)!=0;v=w&x;u=v&(k|0)!=0;t=(l|0)==0;s=(o|0)==0;p=g;q=16;r=0;while(1){if((j|0)==1){if(t){l=1;k=29;break}else{n=e;b=8;m=h}while(1){b=b+-1|0;a[n>>0]=a[m>>0]|0;a[n+1>>0]=a[m>>0]|0;a[n+2>>0]=a[m>>0]|0;a[n+3>>0]=a[m>>0]|0;a[n+4>>0]=a[m>>0]|0;a[n+5>>0]=a[m>>0]|0;a[n+6>>0]=a[m>>0]|0;a[n+7>>0]=a[m>>0]|0;if(!b)break;else{n=n+8|0;m=m+1|0}}}else if((j|0)==2){if(s){l=1;k=29;break}else{n=p;b=e;m=8}while(1){n=n+1|0;m=m+-1|0;a[b>>0]=a[n>>0]|0;a[b+8>>0]=a[n>>0]|0;a[b+16>>0]=a[n>>0]|0;a[b+24>>0]=a[n>>0]|0;a[b+32>>0]=a[n>>0]|0;a[b+40>>0]=a[n>>0]|0;a[b+48>>0]=a[n>>0]|0;a[b+56>>0]=a[n>>0]|0;if(!m)break;else b=b+1|0}}else if(!j){m=p+1|0;do if(!v){if(x){n=((d[m>>0]|0)+2+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)|0)>>>2;b=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2;break}if(w){b=((d[h>>0]|0)+2+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)|0)>>>2;n=b}else{n=128;b=128}}else{n=((d[m>>0]|0)+4+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)+(d[h>>0]|0)+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)|0)>>>3;b=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2}while(0);n=n&255;o=b&255;nd(e|0,n|0,4)|0;nd(e+4|0,o|0,4)|0;nd(e+8|0,n|0,4)|0;nd(e+12|0,o|0,4)|0;nd(e+16|0,n|0,4)|0;nd(e+20|0,o|0,4)|0;g=e+32|0;nd(e+24|0,n|0,4)|0;nd(e+28|0,o|0,4)|0;if(w){o=d[h+4>>0]|0;n=d[h+5>>0]|0;b=d[h+6>>0]|0;m=d[h+7>>0]|0;k=(o+2+n+b+m|0)>>>2;if(x){l=k;n=(o+4+n+b+m+(d[p+5>>0]|0)+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>3}else{l=k;n=k}}else if(x){l=((d[m>>0]|0)+2+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)|0)>>>2;n=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2}else{l=128;n=128}b=l&255;o=n&255;nd(g|0,b|0,4)|0;nd(e+36|0,o|0,4)|0;nd(e+40|0,b|0,4)|0;nd(e+44|0,o|0,4)|0;nd(e+48|0,b|0,4)|0;nd(e+52|0,o|0,4)|0;nd(e+56|0,b|0,4)|0;nd(e+60|0,o|0,4)|0}else{if(!u){l=1;k=29;break}n=d[p+8>>0]|0;b=d[h+7>>0]|0;l=d[p>>0]|0;k=(((d[p+5>>0]|0)-(d[p+3>>0]|0)+((d[p+6>>0]|0)-(d[p+2>>0]|0)<<1)+(((d[p+7>>0]|0)-(d[p+1>>0]|0)|0)*3|0)+(n-l<<2)|0)*17|0)+16>>5;l=(((d[h+4>>0]|0)-(d[h+2>>0]|0)+(b-l<<2)+((d[h+5>>0]|0)-(d[h+1>>0]|0)<<1)+(((d[h+6>>0]|0)-(d[h>>0]|0)|0)*3|0)|0)*17|0)+16>>5;o=Z(k,-3)|0;n=(b+n<<4)+16+(Z(l,-3)|0)|0;b=e;m=8;while(1){m=m+-1|0;g=n+o|0;a[b>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+1>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+2>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+3>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+4>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+5>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+6>>0]=a[(g>>5)+3984>>0]|0;a[b+7>>0]=a[(g+k>>5)+3984>>0]|0;if(!m)break;else{n=n+l|0;b=b+8|0}}}Rb(e,f,q);g=q|1;Rb(e,f+64|0,g);Rb(e,f+128|0,g+1|0);Rb(e,f+192|0,q|3);r=r+1|0;if(r>>>0>=2){l=0;k=29;break}else{p=p+9|0;q=q+4|0;e=e+64|0;h=h+8|0;f=f+256|0}}if((k|0)==29){i=y;return l|0}return 0}function Rb(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;h=i;g=c[e>>2]|0;if((g|0)==16777215){i=h;return}m=f>>>0<16;l=m?16:8;m=m?f:f&3;m=(Z(c[3408+(m<<2)>>2]|0,l)|0)+(c[3344+(m<<2)>>2]|0)|0;n=b+m|0;p=c[e+4>>2]|0;j=b+(m+1)|0;f=d[j>>0]|0;a[n>>0]=a[3472+(g+512+(d[n>>0]|0))>>0]|0;n=c[e+8>>2]|0;k=b+(m+2)|0;o=d[k>>0]|0;a[j>>0]=a[3472+(p+512+f)>>0]|0;g=b+(m+3)|0;j=a[3472+((c[e+12>>2]|0)+512+(d[g>>0]|0))>>0]|0;a[k>>0]=a[3472+(n+512+o)>>0]|0;a[g>>0]=j;g=m+l|0;m=b+g|0;j=c[e+20>>2]|0;k=b+(g+1)|0;o=d[k>>0]|0;a[m>>0]=a[3472+((c[e+16>>2]|0)+512+(d[m>>0]|0))>>0]|0;m=c[e+24>>2]|0;n=b+(g+2)|0;f=d[n>>0]|0;a[k>>0]=a[3472+(j+512+o)>>0]|0;k=b+(g+3)|0;o=a[3472+((c[e+28>>2]|0)+512+(d[k>>0]|0))>>0]|0;a[n>>0]=a[3472+(m+512+f)>>0]|0;a[k>>0]=o;g=g+l|0;k=b+g|0;o=c[e+36>>2]|0;n=b+(g+1)|0;f=d[n>>0]|0;a[k>>0]=a[3472+((c[e+32>>2]|0)+512+(d[k>>0]|0))>>0]|0;k=c[e+40>>2]|0;m=b+(g+2)|0;j=d[m>>0]|0;a[n>>0]=a[3472+(o+512+f)>>0]|0;n=b+(g+3)|0;f=a[3472+((c[e+44>>2]|0)+512+(d[n>>0]|0))>>0]|0;a[m>>0]=a[3472+(k+512+j)>>0]|0;a[n>>0]=f;g=g+l|0;l=b+g|0;n=c[e+52>>2]|0;f=b+(g+1)|0;m=d[f>>0]|0;a[l>>0]=a[3472+((c[e+48>>2]|0)+512+(d[l>>0]|0))>>0]|0;l=c[e+56>>2]|0;j=b+(g+2)|0;k=d[j>>0]|0;a[f>>0]=a[3472+(n+512+m)>>0]|0;g=b+(g+3)|0;f=a[3472+((c[e+60>>2]|0)+512+(d[g>>0]|0))>>0]|0;a[j>>0]=a[3472+(l+512+k)>>0]|0;a[g>>0]=f;i=h;return} +function yc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;q=i;l=b+-1|0;k=a[b+1>>0]|0;m=d[l>>0]|0;n=d[b>>0]|0;r=m-n|0;p=f+4|0;do if((((r|0)>-1?r:0-r|0)>>>0<(c[p>>2]|0)>>>0?(o=d[b+-2>>0]|0,r=o-m|0,j=c[f+8>>2]|0,((r|0)>-1?r:0-r|0)>>>0>>0):0)?(h=k&255,k=h-n|0,((k|0)>-1?k:0-k|0)>>>0>>0):0)if(e>>>0<4){k=d[(c[f>>2]|0)+(e+-1)>>0]|0;k=Oa(~k,k+1|0,4-h+(n-m<<2)+o>>3)|0;o=a[3472+((n|512)-k)>>0]|0;a[l>>0]=a[3472+((m|512)+k)>>0]|0;a[b>>0]=o;break}else{a[l>>0]=(m+2+h+(o<<1)|0)>>>2;a[b>>0]=(n+2+(h<<1)+o|0)>>>2;break}while(0);l=b+g|0;m=b+(g+-1)|0;o=d[m>>0]|0;n=d[l>>0]|0;k=o-n|0;if(((k|0)>-1?k:0-k|0)>>>0>=(c[p>>2]|0)>>>0){i=q;return}k=d[b+(g+-2)>>0]|0;p=k-o|0;j=c[f+8>>2]|0;if(((p|0)>-1?p:0-p|0)>>>0>=j>>>0){i=q;return}h=d[b+(g+1)>>0]|0;g=h-n|0;if(((g|0)>-1?g:0-g|0)>>>0>=j>>>0){i=q;return}if(e>>>0<4){b=d[(c[f>>2]|0)+(e+-1)>>0]|0;b=Oa(~b,b+1|0,4-h+(n-o<<2)+k>>3)|0;g=a[3472+((n|512)-b)>>0]|0;a[m>>0]=a[3472+((o|512)+b)>>0]|0;a[l>>0]=g;i=q;return}else{a[m>>0]=(o+2+h+(k<<1)|0)>>>2;a[l>>0]=(n+2+(h<<1)+k|0)>>>2;i=q;return}}function zc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=i;if(e>>>0<4){n=d[(c[f>>2]|0)+(e+-1)>>0]|0;h=n+1|0;q=0-g|0;e=f+4|0;p=q<<1;o=f+8|0;n=~n;j=8;while(1){m=b+q|0;f=a[b+g>>0]|0;l=d[m>>0]|0;k=d[b>>0]|0;r=l-k|0;if((((r|0)>-1?r:0-r|0)>>>0<(c[e>>2]|0)>>>0?(t=d[b+p>>0]|0,r=t-l|0,s=c[o>>2]|0,((r|0)>-1?r:0-r|0)>>>0>>0):0)?(u=f&255,f=u-k|0,((f|0)>-1?f:0-f|0)>>>0>>0):0){r=Oa(n,h,4-u+(k-l<<2)+t>>3)|0;f=a[3472+((k|512)-r)>>0]|0;a[m>>0]=a[3472+((l|512)+r)>>0]|0;a[b>>0]=f}j=j+-1|0;if(!j)break;else b=b+1|0}i=v;return}else{o=0-g|0;m=f+4|0;n=o<<1;f=f+8|0;l=8;while(1){h=b+o|0;e=a[b+g>>0]|0;j=d[h>>0]|0;k=d[b>>0]|0;s=j-k|0;if((((s|0)>-1?s:0-s|0)>>>0<(c[m>>2]|0)>>>0?(p=d[b+n>>0]|0,s=p-j|0,q=c[f>>2]|0,((s|0)>-1?s:0-s|0)>>>0>>0):0)?(r=e&255,e=r-k|0,((e|0)>-1?e:0-e|0)>>>0>>0):0){a[h>>0]=(j+2+r+(p<<1)|0)>>>2;a[b>>0]=(k+2+(r<<1)+p|0)>>>2}l=l+-1|0;if(!l)break;else b=b+1|0}i=v;return}}function Ac(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;t=i;r=d[(c[f>>2]|0)+(e+-1)>>0]|0;s=r+1|0;l=0-g|0;h=f+4|0;q=l<<1;e=f+8|0;r=~r;l=b+l|0;m=a[b+g>>0]|0;k=d[l>>0]|0;j=d[b>>0]|0;u=k-j|0;f=c[h>>2]|0;if((((u|0)>-1?u:0-u|0)>>>0>>0?(o=d[b+q>>0]|0,u=o-k|0,n=c[e>>2]|0,((u|0)>-1?u:0-u|0)>>>0>>0):0)?(p=m&255,m=p-j|0,((m|0)>-1?m:0-m|0)>>>0>>0):0){p=Oa(r,s,4-p+(j-k<<2)+o>>3)|0;f=a[3472+((j|512)-p)>>0]|0;a[l>>0]=a[3472+((k|512)+p)>>0]|0;a[b>>0]=f;f=c[h>>2]|0}m=b+1|0;j=b+(1-g)|0;k=d[j>>0]|0;l=d[m>>0]|0;p=k-l|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}h=d[b+(q|1)>>0]|0;p=h-k|0;f=c[e>>2]|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}e=d[b+(g+1)>>0]|0;p=e-l|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}o=Oa(r,s,4-e+(l-k<<2)+h>>3)|0;p=a[3472+((l|512)-o)>>0]|0;a[j>>0]=a[3472+((k|512)+o)>>0]|0;a[m>>0]=p;i=t;return}function Bc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;p=c[b+4>>2]|0;q=c[b+8>>2]|0;if(!((d|0)==0|(d|0)==5)?(c[a+3384>>2]|0)==0:0)f=0;else{g=a+1220|0;e=0;do{f=ic(g,e)|0;e=e+1|0}while(e>>>0<16&(f|0)==0)}l=a+1176|0;n=c[l>>2]|0;if(n){m=c[a+1212>>2]|0;e=0;j=0;g=0;do{if(c[m+(j*216|0)+196>>2]|0)break;j=j+1|0;e=e+1|0;o=(e|0)==(p|0);g=(o&1)+g|0;e=o?0:e}while(j>>>0>>0);if((j|0)!=(n|0)){o=a+1212|0;n=c[o>>2]|0;j=Z(g,p)|0;if(e){l=a+1204|0;h=e;do{h=h+-1|0;m=h+j|0;Cc(n+(m*216|0)|0,b,g,h,d,f);c[n+(m*216|0)+196>>2]=1;c[l>>2]=(c[l>>2]|0)+1}while((h|0)!=0)}e=e+1|0;if(e>>>0

>>0){m=a+1204|0;do{l=e+j|0;k=n+(l*216|0)+196|0;if(!(c[k>>2]|0)){Cc(n+(l*216|0)|0,b,g,e,d,f);c[k>>2]=1;c[m>>2]=(c[m>>2]|0)+1}e=e+1|0}while((e|0)!=(p|0))}if(g){if(p){n=g+-1|0;h=Z(n,p)|0;e=a+1204|0;l=0-p|0;k=0;do{m=n;j=(c[o>>2]|0)+((k+h|0)*216|0)|0;while(1){Cc(j,b,m,k,d,f);c[j+196>>2]=1;c[e>>2]=(c[e>>2]|0)+1;if(!m)break;else{m=m+-1|0;j=j+(l*216|0)|0}}k=k+1|0}while((k|0)!=(p|0))}}else g=0;g=g+1|0;if(g>>>0>=q>>>0){i=r;return 0}m=a+1204|0;if(!p){i=r;return 0}do{e=c[o>>2]|0;l=Z(g,p)|0;k=0;do{h=k+l|0;j=e+(h*216|0)+196|0;if(!(c[j>>2]|0)){Cc(e+(h*216|0)|0,b,g,k,d,f);c[j>>2]=1;c[m>>2]=(c[m>>2]|0)+1}k=k+1|0}while((k|0)!=(p|0));g=g+1|0}while((g|0)!=(q|0));i=r;return 0}}if((d|0)==2|(d|0)==7)if((c[a+3384>>2]|0)==0|(f|0)==0)g=13;else g=14;else if(!f)g=13;else g=14;if((g|0)==13)id(c[b>>2]|0,128,Z(p*384|0,q)|0);else if((g|0)==14)hd(c[b>>2]|0,f,Z(p*384|0,q)|0);g=c[l>>2]|0;c[a+1204>>2]=g;if(!g){i=r;return 0}e=c[a+1212>>2]|0;f=0;do{c[e+(f*216|0)+8>>2]=1;f=f+1|0}while(f>>>0>>0);i=r;return 0}function Cc(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0;sa=i;i=i+480|0;qa=sa+96|0;ra=sa+32|0;m=sa+24|0;n=sa;na=c[e+4>>2]|0;u=c[e+8>>2]|0;Na(e,(Z(na,f)|0)+g|0);p=c[e>>2]|0;k=f<<4;l=g<<4;o=(Z(f<<8,na)|0)+l|0;c[b+20>>2]=40;c[b+8>>2]=0;c[b>>2]=6;c[b+12>>2]=0;c[b+16>>2]=0;c[b+24>>2]=0;do if((h|0)==2|(h|0)==7)id(qa,0,384);else{c[m>>2]=0;c[n+4>>2]=na;c[n+8>>2]=u;c[n>>2]=j;if(!j){id(qa,0,384);break}dc(qa,m,n,l,k,0,0,16,16);sc(e,qa);i=sa;return}while(0);id(ra,0,64);if((f|0)!=0?(c[b+((0-na|0)*216|0)+196>>2]|0)!=0:0){v=o-(na<<4)|0;E=v|1;D=v|3;E=(d[p+E>>0]|0)+(d[p+v>>0]|0)+(d[p+(E+1)>>0]|0)+(d[p+D>>0]|0)|0;$=v|7;D=(d[p+(D+2)>>0]|0)+(d[p+(D+1)>>0]|0)+(d[p+(D+3)>>0]|0)+(d[p+$>>0]|0)|0;F=(d[p+($+2)>>0]|0)+(d[p+($+1)>>0]|0)+(d[p+($+3)>>0]|0)+(d[p+($+4)>>0]|0)|0;v=(d[p+($+6)>>0]|0)+(d[p+($+5)>>0]|0)+(d[p+($+7)>>0]|0)+(d[p+(v|15)>>0]|0)|0;$=D+E|0;c[ra>>2]=F+$+(c[ra>>2]|0)+v;s=ra+4|0;c[s>>2]=$-F-v+(c[s>>2]|0);s=1}else{E=0;D=0;F=0;v=0;s=0}if((u+-1|0)!=(f|0)?(c[b+(na*216|0)+196>>2]|0)!=0:0){z=o+(na<<8)|0;w=z|1;x=z|3;w=(d[p+w>>0]|0)+(d[p+z>>0]|0)+(d[p+(w+1)>>0]|0)+(d[p+x>>0]|0)|0;r=z|7;x=(d[p+(x+2)>>0]|0)+(d[p+(x+1)>>0]|0)+(d[p+(x+3)>>0]|0)+(d[p+r>>0]|0)|0;y=(d[p+(r+2)>>0]|0)+(d[p+(r+1)>>0]|0)+(d[p+(r+3)>>0]|0)+(d[p+(r+4)>>0]|0)|0;z=(d[p+(r+6)>>0]|0)+(d[p+(r+5)>>0]|0)+(d[p+(r+7)>>0]|0)+(d[p+(z|15)>>0]|0)|0;r=x+w|0;c[ra>>2]=y+r+(c[ra>>2]|0)+z;t=ra+4|0;c[t>>2]=r-y-z+(c[t>>2]|0);t=1;r=s+1|0}else{t=0;w=0;x=0;y=0;z=0;r=s}if((g|0)!=0?(c[b+-20>>2]|0)!=0:0){_=o+-1|0;$=na<<4;j=na<<5;ma=na*48|0;C=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;h=na<<6;_=_+h|0;B=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;_=_+h|0;A=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;h=_+h|0;ma=(d[p+(h+$)>>0]|0)+(d[p+h>>0]|0)+(d[p+(h+j)>>0]|0)+(d[p+(h+ma)>>0]|0)|0;h=B+C|0;c[ra>>2]=A+h+(c[ra>>2]|0)+ma;j=ra+16|0;c[j>>2]=h-A-ma+(c[j>>2]|0);j=r+1|0;h=1}else{j=r;C=0;B=0;A=0;ma=0;h=0}do if((na+-1|0)!=(g|0)?(c[b+412>>2]|0)!=0:0){$=o+16|0;n=na<<4;m=na<<5;o=na*48|0;b=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;q=na<<6;$=$+q|0;l=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;$=$+q|0;k=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;q=$+q|0;o=(d[p+(q+n)>>0]|0)+(d[p+q>>0]|0)+(d[p+(q+m)>>0]|0)+(d[p+(q+o)>>0]|0)|0;p=j+1|0;q=h+1|0;j=l+b|0;c[ra>>2]=k+j+(c[ra>>2]|0)+o;m=ra+16|0;j=j-k-o+(c[m>>2]|0)|0;c[m>>2]=j;m=(r|0)==0;n=(h|0)!=0;if(!(m&n)){if(!m){m=1;j=p;h=q;l=21;break}}else c[ra+4>>2]=A+ma+B+C-b-l-k-o>>5;m=1;o=(s|0)!=0;b=(t|0)!=0;h=q;l=27}else l=17;while(0);if((l|0)==17){n=(h|0)!=0;if(!r){m=0;p=j;l=23}else{m=0;l=21}}if((l|0)==21){p=ra+4|0;c[p>>2]=c[p>>2]>>r+3;p=j;l=23}do if((l|0)==23){j=(h|0)==0;o=(s|0)!=0;b=(t|0)!=0;if(j&o&b){c[ra+16>>2]=F+v+D+E-z-y-x-w>>5;pa=m;h=p;oa=n;o=1;b=1;break}if(j){pa=m;h=p;oa=n}else{j=c[ra+16>>2]|0;l=27}}while(0);if((l|0)==27){c[ra+16>>2]=j>>h+3;pa=m;h=p;oa=n}if((h|0)==1)c[ra>>2]=c[ra>>2]>>4;else if((h|0)==2)c[ra>>2]=c[ra>>2]>>5;else if((h|0)==3)c[ra>>2]=(c[ra>>2]|0)*21>>10;else c[ra>>2]=c[ra>>2]>>6;Dc(ra);n=0;j=qa;m=ra;while(1){h=c[m+((n>>>2&3)<<2)>>2]|0;if((h|0)<0)h=0;else h=(h|0)>255?-1:h&255;a[j>>0]=h;h=n+1|0;if((h|0)==256)break;else{n=h;j=j+1|0;m=(h&63|0)==0?m+16|0:m}}ta=Z(u,na)|0;V=na<<3;Y=0-V|0;G=Y|1;_=G+1|0;$=Y|3;aa=$+1|0;ba=$+2|0;ca=$+3|0;da=Y|7;W=ra+4|0;ka=na<<6;H=ka|1;ea=H+1|0;fa=ka|3;ga=fa+1|0;ha=fa+2|0;ia=fa+3|0;ja=ka|7;I=V+-1|0;U=na<<4;J=U+-1|0;K=J+V|0;L=J+U|0;M=L+V|0;N=L+U|0;O=N+V|0;X=ra+16|0;P=V+8|0;Q=U|8;R=Q+V|0;S=Q+U|0;T=S+V|0;U=S+U|0;V=U+V|0;la=ta<<6;q=E;p=D;h=F;t=v;n=w;j=x;l=y;u=z;F=0;m=C;k=B;r=A;s=ma;E=(c[e>>2]|0)+((Z(f<<6,na)|0)+(g<<3)+(ta<<8))|0;while(1){id(ra,0,64);if(o){q=(d[E+G>>0]|0)+(d[E+Y>>0]|0)|0;p=(d[E+$>>0]|0)+(d[E+_>>0]|0)|0;z=(d[E+ba>>0]|0)+(d[E+aa>>0]|0)|0;A=(d[E+da>>0]|0)+(d[E+ca>>0]|0)|0;t=p+q|0;c[ra>>2]=z+t+(c[ra>>2]|0)+A;c[W>>2]=t-z-A+(c[W>>2]|0);t=1}else{z=h;A=t;t=0}if(b){B=(d[E+H>>0]|0)+(d[E+ka>>0]|0)|0;C=(d[E+fa>>0]|0)+(d[E+ea>>0]|0)|0;D=(d[E+ha>>0]|0)+(d[E+ga>>0]|0)|0;u=(d[E+ja>>0]|0)+(d[E+ia>>0]|0)|0;h=C+B|0;c[ra>>2]=D+h+(c[ra>>2]|0)+u;c[W>>2]=h-D-u+(c[W>>2]|0);h=t+1|0}else{B=n;C=j;D=l;h=t}if(oa){v=(d[E+I>>0]|0)+(d[E+-1>>0]|0)|0;w=(d[E+K>>0]|0)+(d[E+J>>0]|0)|0;x=(d[E+M>>0]|0)+(d[E+L>>0]|0)|0;y=(d[E+O>>0]|0)+(d[E+N>>0]|0)|0;t=w+v|0;c[ra>>2]=x+t+(c[ra>>2]|0)+y;c[X>>2]=t-x-y+(c[X>>2]|0);t=h+1|0;s=1}else{t=h;v=m;w=k;x=r;y=s;s=0}do if(pa){l=(d[E+P>>0]|0)+(d[E+8>>0]|0)|0;m=(d[E+R>>0]|0)+(d[E+Q>>0]|0)|0;j=(d[E+T>>0]|0)+(d[E+S>>0]|0)|0;n=(d[E+V>>0]|0)+(d[E+U>>0]|0)|0;t=t+1|0;s=s+1|0;k=m+l|0;c[ra>>2]=j+k+(c[ra>>2]|0)+n;k=k-j-n+(c[X>>2]|0)|0;c[X>>2]=k;r=(h|0)==0;if(!(r&oa))if(r){l=54;break}else{l=49;break}else{c[W>>2]=x+y+w+v-l-m-j-n>>4;l=54;break}}else if(!h){r=s;l=50}else l=49;while(0);if((l|0)==49){c[W>>2]=c[W>>2]>>h+2;r=s;l=50}do if((l|0)==50){l=0;s=(r|0)==0;if(s&o&b){c[X>>2]=z+A+p+q-u-D-C-B>>4;break}if(!s){k=c[X>>2]|0;s=r;l=54}}while(0);if((l|0)==54)c[X>>2]=k>>s+2;if((t|0)==1)c[ra>>2]=c[ra>>2]>>3;else if((t|0)==2)c[ra>>2]=c[ra>>2]>>4;else if((t|0)==3)c[ra>>2]=(c[ra>>2]|0)*21>>9;else c[ra>>2]=c[ra>>2]>>5;Dc(ra);s=0;r=qa+((F<<6)+256)|0;k=ra;while(1){t=c[k+((s>>>1&3)<<2)>>2]|0;if((t|0)<0)t=0;else t=(t|0)>255?-1:t&255;a[r>>0]=t;t=s+1|0;if((t|0)==64)break;else{s=t;r=r+1|0;k=(t&15|0)==0?k+16|0:k}}F=F+1|0;if((F|0)==2)break;else{h=z;t=A;n=B;j=C;l=D;m=v;k=w;r=x;s=y;E=E+la|0}}sc(e,qa);i=sa;return}function Dc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;h=i;f=a+4|0;b=c[f>>2]|0;g=a+16|0;d=c[g>>2]|0;e=c[a>>2]|0;if(!(b|d)){c[a+60>>2]=e;c[a+56>>2]=e;c[a+52>>2]=e;c[a+48>>2]=e;c[a+44>>2]=e;c[a+40>>2]=e;c[a+36>>2]=e;c[a+32>>2]=e;c[a+28>>2]=e;c[a+24>>2]=e;c[a+20>>2]=e;c[g>>2]=e;c[a+12>>2]=e;c[a+8>>2]=e;c[f>>2]=e;i=h;return}else{k=b+e|0;g=b>>1;j=g+e|0;g=e-g|0;b=e-b|0;c[a>>2]=d+k;e=d>>1;c[a+16>>2]=e+k;c[a+32>>2]=k-e;c[a+48>>2]=k-d;c[f>>2]=d+j;c[a+20>>2]=e+j;c[a+36>>2]=j-e;c[a+52>>2]=j-d;c[a+8>>2]=d+g;c[a+24>>2]=e+g;c[a+40>>2]=g-e;c[a+56>>2]=g-d;c[a+12>>2]=d+b;c[a+28>>2]=e+b;c[a+44>>2]=b-e;c[a+60>>2]=b-d;i=h;return}}function Ec(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;id(b,0,952);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b>>2]=d&1;do if(d){d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+4>>2]=d;if((d|0)==255){d=jb(a,16)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+8>>2]=d;d=jb(a,16)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+12>>2]=d;break}}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+16>>2]=d&1;do if(d){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+20>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+24>>2]=d&1;do if(d){d=jb(a,3)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+28>>2]=d;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+32>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+36>>2]=d&1;if(!d){c[b+40>>2]=2;c[b+44>>2]=2;c[b+48>>2]=2;break}d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+40>>2]=d;d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+44>>2]=d;d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+48>>2]=d;break}}else{c[b+28>>2]=5;c[b+40>>2]=2;c[b+44>>2]=2;c[b+48>>2]=2}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+52>>2]=d&1;if(d){d=b+56|0;e=nb(a,d)|0;if(e){d=e;i=h;return d|0}if((c[d>>2]|0)>>>0>5){d=1;i=h;return d|0}d=b+60|0;e=nb(a,d)|0;if(e){d=e;i=h;return d|0}if((c[d>>2]|0)>>>0>5){d=1;i=h;return d|0}}d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+64>>2]=d&1;do if(d){d=kb(a)|0;if((lb(a,32)|0)==-1|(d|0)==0){d=1;i=h;return d|0}c[b+68>>2]=d;d=kb(a)|0;if((lb(a,32)|0)==-1|(d|0)==0){d=1;i=h;return d|0}c[b+72>>2]=d;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+76>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;f=b+80|0;c[f>>2]=d&1;if(d){e=Fc(a,b+84|0)|0;if(e){d=e;i=h;return d|0}}else{c[b+84>>2]=1;c[b+96>>2]=288000001;c[b+224>>2]=288000001;c[b+480>>2]=24;c[b+484>>2]=24;c[b+488>>2]=24;c[b+492>>2]=24}e=jb(a,1)|0;if((e|0)==-1){d=1;i=h;return d|0}e=(e|0)==1;d=b+496|0;c[d>>2]=e&1;if(e){e=Fc(a,b+500|0)|0;if(e){d=e;i=h;return d|0}}else{c[b+500>>2]=1;c[b+512>>2]=240000001;c[b+640>>2]=240000001;c[b+896>>2]=24;c[b+900>>2]=24;c[b+904>>2]=24;c[b+908>>2]=24}if(!((c[f>>2]|0)==0?(c[d>>2]|0)==0:0))g=46;do if((g|0)==46){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+912>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+916>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+920>>2]=d&1;do if(d){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+924>>2]=(d|0)==1&1;e=b+928|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+932|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+936|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+940|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}d=nb(a,b+944|0)|0;if(d){i=h;return d|0}d=nb(a,b+948|0)|0;if(!d)break;i=h;return d|0}else{c[b+924>>2]=1;c[b+928>>2]=2;c[b+932>>2]=1;c[b+936>>2]=16;c[b+940>>2]=16;c[b+944>>2]=16;c[b+948>>2]=16}while(0);d=0;i=h;return d|0}function Fc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;d=nb(a,b)|0;if(d){i=k;return d|0}d=(c[b>>2]|0)+1|0;c[b>>2]=d;if(d>>>0>32){d=1;i=k;return d|0}d=jb(a,4)|0;if((d|0)==-1){d=1;i=k;return d|0}j=b+4|0;c[j>>2]=d;e=jb(a,4)|0;if((e|0)==-1){d=1;i=k;return d|0}h=b+8|0;c[h>>2]=e;a:do if(c[b>>2]|0){g=0;while(1){f=b+(g<<2)+12|0;d=nb(a,f)|0;if(d){e=17;break}e=c[f>>2]|0;if((e|0)==-1){d=1;e=17;break}d=e+1|0;c[f>>2]=d;c[f>>2]=d<<(c[j>>2]|0)+6;f=b+(g<<2)+140|0;d=nb(a,f)|0;if(d){e=17;break}e=c[f>>2]|0;if((e|0)==-1){d=1;e=17;break}e=e+1|0;c[f>>2]=e;c[f>>2]=e<<(c[h>>2]|0)+4;e=jb(a,1)|0;if((e|0)==-1){d=1;e=17;break}c[b+(g<<2)+268>>2]=(e|0)==1&1;g=g+1|0;if(g>>>0>=(c[b>>2]|0)>>>0)break a}if((e|0)==17){i=k;return d|0}}while(0);d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+396>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+400>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+404>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+408>>2]=d;d=0;i=k;return d|0}function Gc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;a:do if(!(c[d+284>>2]|0))o=0;else{h=0;while(1){j=c[d+(h*20|0)+288>>2]|0;if((j|0)==5){o=1;break a}else if(!j)break;h=h+1|0}o=0}while(0);j=c[b+16>>2]|0;if((j|0)==1){if((c[e>>2]|0)!=5){f=c[a+12>>2]|0;if((c[a+8>>2]|0)>>>0>(c[d+12>>2]|0)>>>0)f=(c[b+12>>2]|0)+f|0}else f=0;m=c[b+36>>2]|0;h=(m|0)==0;if(h)j=0;else j=(c[d+12>>2]|0)+f|0;e=(c[e+4>>2]|0)==0;k=((e&(j|0)!=0)<<31>>31)+j|0;l=(k|0)!=0;if(l){g=k+-1|0;n=(g>>>0)%(m>>>0)|0;g=(g>>>0)/(m>>>0)|0}else{n=0;g=0}if(h)j=0;else{k=c[b+40>>2]|0;j=0;h=0;do{j=(c[k+(h<<2)>>2]|0)+j|0;h=h+1|0}while(h>>>0>>0)}if(l){g=Z(j,g)|0;k=c[b+40>>2]|0;j=0;do{g=(c[k+(j<<2)>>2]|0)+g|0;j=j+1|0}while(j>>>0<=n>>>0)}else g=0;if(e)j=(c[b+28>>2]|0)+g|0;else j=g;g=(c[d+32>>2]|0)+(c[b+32>>2]|0)|0;h=a+12|0;if(!o){b=((g|0)<0?g:0)+j+(c[d+28>>2]|0)|0;c[h>>2]=f;c[a+8>>2]=c[d+12>>2];i=p;return b|0}else{c[h>>2]=0;c[a+8>>2]=0;b=0;i=p;return b|0}}else if(!j){if((c[e>>2]|0)!=5){h=c[a>>2]|0;j=c[d+20>>2]|0;if(h>>>0>j>>>0?(k=c[b+20>>2]|0,(h-j|0)>>>0>=k>>>1>>>0):0){h=(c[a+4>>2]|0)+k|0;k=a}else{k=a;m=11}}else{c[a+4>>2]=0;c[a>>2]=0;j=c[d+20>>2]|0;h=0;k=a;m=11}do if((m|0)==11){if(j>>>0>h>>>0?(g=c[b+20>>2]|0,(j-h|0)>>>0>g>>>1>>>0):0){h=(c[a+4>>2]|0)-g|0;break}h=c[a+4>>2]|0}while(0);if(!(c[e+4>>2]|0)){b=c[d+24>>2]|0;b=j+h+((b|0)<0?b:0)|0;i=p;return b|0}c[a+4>>2]=h;f=c[d+24>>2]|0;g=(f|0)<0;if(!o){c[k>>2]=j;b=j+h+(g?f:0)|0;i=p;return b|0}else{c[a+4>>2]=0;c[k>>2]=g?0-f|0:0;b=0;i=p;return b|0}}else{if((c[e>>2]|0)==5){k=0;g=0;f=a+12|0}else{j=c[d+12>>2]|0;f=a+12|0;h=c[f>>2]|0;if((c[a+8>>2]|0)>>>0>j>>>0)h=(c[b+12>>2]|0)+h|0;k=h;g=(j+h<<1)+(((c[e+4>>2]|0)==0)<<31>>31)|0}if(!o){c[f>>2]=k;c[a+8>>2]=c[d+12>>2];b=g;i=p;return b|0}else{c[f>>2]=0;c[a+8>>2]=0;b=0;i=p;return b|0}}return 0}function Hc(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;Ab(a);e=fd(2112)|0;c[a+3376>>2]=e;if(e)if(!b)b=0;else{c[a+1216>>2]=1;b=0}else b=1;i=d;return b|0}function Ic(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;i=i+208|0;l=r+204|0;p=r;g=r+112|0;h=r+40|0;q=r+16|0;j=r+12|0;n=r+8|0;c[j>>2]=0;o=a+3344|0;if((c[o>>2]|0)!=0?(c[a+3348>>2]|0)==(b|0):0){b=a+3356|0;c[q+0>>2]=c[b+0>>2];c[q+4>>2]=c[b+4>>2];c[q+8>>2]=c[b+8>>2];c[q+12>>2]=c[b+12>>2];c[q+4>>2]=c[q>>2];c[q+8>>2]=0;c[q+16>>2]=0;c[f>>2]=c[a+3352>>2]}else k=4;do if((k|0)==4)if(!(Pa(b,d,q,f)|0)){d=a+3356|0;c[d+0>>2]=c[q+0>>2];c[d+4>>2]=c[q+4>>2];c[d+8>>2]=c[q+8>>2];c[d+12>>2]=c[q+12>>2];c[d+16>>2]=c[q+16>>2];c[a+3352>>2]=c[f>>2];c[a+3348>>2]=b;break}else{n=3;i=r;return n|0}while(0);c[o>>2]=0;if(sb(q,p)|0){n=3;i=r;return n|0}if(((c[p>>2]|0)+-1|0)>>>0>11){n=0;i=r;return n|0}b=Ib(q,p,a,j)|0;if(!b){do if(!(c[j>>2]|0))k=19;else{if((c[a+1184>>2]|0)!=0?(c[a+16>>2]|0)!=0:0){if(c[a+3380>>2]|0){n=3;i=r;return n|0}if(!(c[a+1188>>2]|0)){m=a+1220|0;n=a+1336|0;c[n>>2]=jc(m)|0;nc(m);Bc(a,n,0)|0}else Bc(a,a+1336|0,c[a+1372>>2]|0)|0;c[f>>2]=0;c[o>>2]=1;c[a+1180>>2]=0;g=a+1336|0;b=a+1360|0;break}c[a+1188>>2]=0;c[a+1180>>2]=0;k=19}while(0);do if((k|0)==19){b=c[p>>2]|0;if((b|0)==7)if(!(Qa(q,g)|0)){Bb(a,g)|0;n=0;i=r;return n|0}else{n=g+40|0;gd(c[n>>2]|0);c[n>>2]=0;n=g+84|0;gd(c[n>>2]|0);c[n>>2]=0;n=3;i=r;return n|0}else if((b|0)==1|(b|0)==5){k=a+1180|0;if(c[a+1180>>2]|0){n=0;i=r;return n|0}c[a+1184>>2]=1;if(Fb(a)|0){c[a+1204>>2]=0;c[a+1208>>2]=e;Ua(q,l)|0;j=a+8|0;d=c[j>>2]|0;b=Db(a,c[l>>2]|0,(c[p>>2]|0)==5&1)|0;if(b){c[a+4>>2]=256;c[a+12>>2]=0;c[j>>2]=32;c[a+16>>2]=0;c[a+3380>>2]=0;n=(b|0)==65535?5:4;i=r;return n|0}if((d|0)!=(c[j>>2]|0)){d=c[a+16>>2]|0;c[n>>2]=1;b=c[a>>2]|0;if(b>>>0<32)b=c[a+(b<<2)+20>>2]|0;else b=0;c[f>>2]=0;c[o>>2]=1;if((((((c[p>>2]|0)==5?(l=_a(n,q,d,c[a+12>>2]|0,5)|0,(c[n>>2]|l|0)==0):0)?(m=a+1220|0,!((c[a+1276>>2]|0)!=0|(b|0)==0)):0)?(c[b+52>>2]|0)==(c[d+52>>2]|0):0)?(c[b+56>>2]|0)==(c[d+56>>2]|0):0)?(c[b+88>>2]|0)==(c[d+88>>2]|0):0)qc(m);else c[a+1280>>2]=0;c[a>>2]=c[j>>2];n=2;i=r;return n|0}}if(c[a+3380>>2]|0){n=3;i=r;return n|0}h=a+1368|0;j=a+2356|0;b=a+16|0;if(Ta(q,j,c[b>>2]|0,c[a+12>>2]|0,p)|0){n=3;i=r;return n|0}if(!(Fb(a)|0))d=a+1220|0;else{d=a+1220|0;if((c[p>>2]|0)!=5?(oc(d,c[a+2368>>2]|0,(c[p+4>>2]|0)!=0&1,c[(c[b>>2]|0)+48>>2]|0)|0)!=0:0){n=3;i=r;return n|0}c[a+1336>>2]=jc(d)|0}od(h|0,j|0,988)|0;c[a+1188>>2]=1;b=a+1360|0;l=p;m=c[l+4>>2]|0;n=b;c[n>>2]=c[l>>2];c[n+4>>2]=m;Hb(a,c[a+1432>>2]|0);nc(d);if(gc(d,a+1436|0,c[a+1380>>2]|0,c[a+1412>>2]|0)|0){n=3;i=r;return n|0}g=a+1336|0;if($a(q,a,g,h)|0){ab(a,c[h>>2]|0);n=3;i=r;return n|0}if(!(Gb(a)|0)){n=0;i=r;return n|0}else{c[k>>2]=1;break}}else if((b|0)==8)if(!(Sa(q,h)|0)){Cb(a,h)|0;n=0;i=r;return n|0}else{n=h+20|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+24|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+28|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+44|0;gd(c[n>>2]|0);c[n>>2]=0;n=3;i=r;return n|0}else{n=0;i=r;return n|0}}while(0);uc(g,c[a+1212>>2]|0);Eb(a);j=Gc(a+1284|0,c[a+16>>2]|0,a+1368|0,b)|0;d=a+1188|0;do if(c[d>>2]|0){h=a+1220|0;if(!(c[a+1364>>2]|0)){hc(h,0,g,c[a+1380>>2]|0,j,(c[b>>2]|0)==5&1,c[a+1208>>2]|0,c[a+1204>>2]|0)|0;break}else{hc(h,a+1644|0,g,c[a+1380>>2]|0,j,(c[b>>2]|0)==5&1,c[a+1208>>2]|0,c[a+1204>>2]|0)|0;break}}while(0);c[a+1184>>2]=0;c[d>>2]=0;n=1;i=r;return n|0}else if((b|0)==65520){n=4;i=r;return n|0}else{n=3;i=r;return n|0}return 0}function Jc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;e=0;do{d=a+(e<<2)+20|0;b=c[d>>2]|0;if(b){gd(c[b+40>>2]|0);c[(c[d>>2]|0)+40>>2]=0;gd(c[(c[d>>2]|0)+84>>2]|0);c[(c[d>>2]|0)+84>>2]=0;gd(c[d>>2]|0);c[d>>2]=0}e=e+1|0}while((e|0)!=32);e=0;do{d=a+(e<<2)+148|0;b=c[d>>2]|0;if(b){gd(c[b+20>>2]|0);c[(c[d>>2]|0)+20>>2]=0;gd(c[(c[d>>2]|0)+24>>2]|0);c[(c[d>>2]|0)+24>>2]=0;gd(c[(c[d>>2]|0)+28>>2]|0);c[(c[d>>2]|0)+28>>2]=0;gd(c[(c[d>>2]|0)+44>>2]|0);c[(c[d>>2]|0)+44>>2]=0;gd(c[d>>2]|0);c[d>>2]=0}e=e+1|0}while((e|0)!=256);b=a+3376|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+1212|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+1172|0;gd(c[b>>2]|0);c[b>>2]=0;mc(a+1220|0);i=f;return}function Kc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=i;a=pc(a+1220|0)|0;if(!a){a=0;i=f;return a|0}c[b>>2]=c[a+4>>2];c[d>>2]=c[a+12>>2];c[e>>2]=c[a+8>>2];a=c[a>>2]|0;i=f;return a|0}function Lc(a){a=a|0;var b=0;b=i;a=c[a+16>>2]|0;if(!a){a=0;i=b;return a|0}a=c[a+52>>2]|0;i=b;return a|0}function Mc(a){a=a|0;var b=0;b=i;a=c[a+16>>2]|0;if(!a){a=0;i=b;return a|0}a=c[a+56>>2]|0;i=b;return a|0}function Nc(a){a=a|0;var b=0;b=i;qc(a+1220|0);i=b;return}function Oc(a){a=a|0;var b=0;b=i;a=(Jb(a)|0)==0&1;i=b;return a|0}function Pc(a){a=a|0;var b=0,d=0;d=i;a=c[a+16>>2]|0;if(((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(b=c[a+84>>2]|0,(b|0)!=0):0)?(c[b+24>>2]|0)!=0:0)?(c[b+32>>2]|0)!=0:0){a=1;i=d;return a|0}a=0;i=d;return a|0}function Qc(a){a=a|0;var b=0,d=0;d=i;a=c[a+16>>2]|0;if(((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(b=c[a+84>>2]|0,(b|0)!=0):0)?(c[b+24>>2]|0)!=0:0)?(c[b+36>>2]|0)!=0:0)a=c[b+48>>2]|0;else a=2;i=d;return a|0}function Rc(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0;h=i;a=c[a+16>>2]|0;if((a|0)!=0?(c[a+60>>2]|0)!=0:0){c[b>>2]=1;b=a+64|0;c[d>>2]=c[b>>2]<<1;c[e>>2]=(c[a+52>>2]<<4)-((c[a+68>>2]|0)+(c[b>>2]|0)<<1);b=a+72|0;c[f>>2]=c[b>>2]<<1;a=(c[a+56>>2]<<4)-((c[a+76>>2]|0)+(c[b>>2]|0)<<1)|0;c[g>>2]=a;i=h;return}c[b>>2]=0;c[d>>2]=0;c[e>>2]=0;c[f>>2]=0;a=0;c[g>>2]=a;i=h;return}function Sc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;f=i;a=c[a+16>>2]|0;a:do if((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(e=c[a+84>>2]|0,(e|0)!=0):0)?(c[e>>2]|0)!=0:0){a=c[e+4>>2]|0;do switch(a|0){case 8:{e=11;a=32;break a}case 13:{e=99;a=160;break a}case 12:{e=33;a=64;break a}case 6:{e=11;a=24;break a}case 7:{e=11;a=20;break a}case 255:{a=c[e+8>>2]|0;e=c[e+12>>2]|0;g=(a|0)==0|(e|0)==0;e=g?0:e;a=g?0:a;break a}case 5:{e=33;a=40;break a}case 4:{e=11;a=16;break a}case 3:{e=11;a=10;break a}case 1:case 0:{e=a;break a}case 2:{e=11;a=12;break a}case 10:{e=11;a=18;break a}case 9:{e=33;a=80;break a}case 11:{e=11;a=15;break a}default:{e=0;a=0;break a}}while(0)}else{e=1;a=1}while(0);c[b>>2]=a;c[d>>2]=e;i=f;return}function Tc(a){a=a|0;a=c[a+16>>2]|0;if(!a)a=0;else a=c[a>>2]|0;return a|0}function Uc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;do if(a){d=fd(3396)|0;if(d){e=d+8|0;if(!(Hc(e,b)|0)){c[d>>2]=1;c[d+4>>2]=0;c[a>>2]=d;d=0;break}else{Jc(e);gd(d);d=-4;break}}else d=-4}else d=-1;while(0);i=f;return d|0}function Vc(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;if((a|0)==0|(b|0)==0){a=-1;i=e;return a|0}d=a+8|0;if(!(c[a+24>>2]|0)){a=-6;i=e;return a|0}if(!(c[a+20>>2]|0)){a=-6;i=e;return a|0}c[b+4>>2]=(Lc(d)|0)<<4;c[b+8>>2]=(Mc(d)|0)<<4;c[b+12>>2]=Pc(d)|0;c[b+16>>2]=Qc(d)|0;Rc(d,b+28|0,b+32|0,b+36|0,b+40|0,b+44|0);Sc(d,b+20|0,b+24|0);c[b>>2]=Tc(d)|0;a=0;i=e;return a|0}function Wc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;m=i;i=i+16|0;j=m;a:do if((!((b|0)==0|(d|0)==0)?(f=c[b>>2]|0,(f|0)!=0):0)?(g=c[b+4>>2]|0,(g|0)!=0):0)if((a|0)!=0?(e=c[a>>2]|0,(e|0)!=0):0){c[d>>2]=0;c[j>>2]=0;k=a+8|0;c[a+3392>>2]=c[b+12>>2];h=b+8|0;b=1;while(1){if((e|0)==2){l=8;break}e=Ic(k,f,g,c[h>>2]|0,j)|0;n=c[j>>2]|0;f=f+n|0;g=g-n|0;g=(g|0)<0?0:g;c[d>>2]=f;if((e|0)==5){b=-4;break a}else if((e|0)==4){e=(Oc(k)|0|g|0)==0;b=e?-2:b}else if((e|0)==2)break;else if((e|0)==1){l=13;break}if(!g)break a;e=c[a>>2]|0}if((l|0)==8){c[a>>2]=1;c[d>>2]=f+(c[j>>2]|0)}else if((l|0)==13){b=a+4|0;c[b>>2]=(c[b>>2]|0)+1;b=(g|0)==0?2:3;break}b=a+1288|0;if((c[b>>2]|0)!=0?(c[a+1244>>2]|0)!=(c[a+1248>>2]|0):0){c[b>>2]=0;c[a>>2]=2;b=3}else b=4}else b=-3;else b=-1;while(0);i=m;return b|0}function Xc(a){a=a|0;c[a>>2]=2;c[a+4>>2]=3;return}function Yc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;h=i;i=i+16|0;f=h+8|0;e=h+4|0;g=h;if((a|0)==0|(b|0)==0){a=-1;i=h;return a|0}a=a+8|0;if(d)Nc(a);a=Kc(a,g,e,f)|0;if(!a){a=0;i=h;return a|0}c[b>>2]=a;c[b+4>>2]=c[g>>2];c[b+8>>2]=c[e>>2];c[b+12>>2]=c[f>>2];a=2;i=h;return a|0}function Zc(a){a=a|0;var b=0,d=0;d=i;b=jd(a)|0;c[1792]=b;c[1791]=b;c[1790]=a;c[1793]=b+a;i=d;return b|0}function _c(a){a=a|0;c[1790]=a;return}function $c(){var a=0;a=i;c[1786]=c[1791];c[1787]=c[1790];do bd()|0;while((c[1787]|0)!=0);i=a;return}function ad(){var a=0,b=0;b=i;if(Uc(7176,0)|0){da(7280)|0;a=c[1784]|0;if(a)kd(a)}else{c[1796]=1;c[1798]=1}i=b;return -1}function bd(){var a=0,b=0,d=0;b=i;c[1788]=c[1798];a=Wc(c[1794]|0,7144,7200)|0;switch(a|0){case 1:case -2:{c[1787]=0;i=b;return a|0}case 4:{if(Vc(c[1794]|0,7208)|0){a=-1;i=b;return a|0}c[1814]=(Z((c[1803]|0)*3|0,c[1804]|0)|0)>>>1;ra();a=c[1800]|0;c[1787]=(c[1786]|0)-a+(c[1787]|0);c[1786]=a;a=0;i=b;return a|0}case 2:{c[1787]=0;break}case 3:{d=c[1800]|0;c[1787]=(c[1786]|0)-d+(c[1787]|0);c[1786]=d;break}default:{i=b;return a|0}}c[1798]=(c[1798]|0)+1;if((Yc(c[1794]|0,7264,0)|0)!=2){i=b;return a|0}do{c[1796]=(c[1796]|0)+1;ca(c[1816]|0,c[1803]|0,c[1804]|0)}while((Yc(c[1794]|0,7264,0)|0)==2);i=b;return a|0}function cd(){var a=0,b=0;b=i;a=c[1784]|0;if(a)kd(a);i=b;return}function dd(){var a=0,b=0;b=i;i=i+16|0;a=b;Xc(a);i=b;return c[a>>2]|0}function ed(){var a=0,b=0;b=i;i=i+16|0;a=b;Xc(a);i=b;return c[a+4>>2]|0}function fd(a){a=a|0;var b=0;b=i;a=jd(a)|0;i=b;return a|0}function gd(a){a=a|0;var b=0;b=i;kd(a);i=b;return}function hd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=i;od(a|0,b|0,c|0)|0;i=d;return}function id(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=i;nd(a|0,b&255|0,c|0)|0;i=d;return}function jd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0;L=i;do if(a>>>0<245){if(a>>>0<11)p=16;else p=a+11&-8;a=p>>>3;l=c[1828]|0;k=l>>>a;if(k&3){g=(k&1^1)+a|0;b=g<<1;h=7352+(b<<2)|0;b=7352+(b+2<<2)|0;e=c[b>>2]|0;j=e+8|0;f=c[j>>2]|0;do if((h|0)!=(f|0)){if(f>>>0<(c[1832]|0)>>>0)ka();d=f+12|0;if((c[d>>2]|0)==(e|0)){c[d>>2]=h;c[b>>2]=f;break}else ka()}else c[1828]=l&~(1<>2]=x|3;x=e+(x|4)|0;c[x>>2]=c[x>>2]|1;x=j;i=L;return x|0}j=c[1830]|0;if(p>>>0>j>>>0){if(k){g=2<>>12&16;g=g>>>a;h=g>>>5&8;g=g>>>h;d=g>>>2&4;g=g>>>d;e=g>>>1&2;g=g>>>e;f=g>>>1&1;f=(h|a|d|e|f)+(g>>>f)|0;g=f<<1;e=7352+(g<<2)|0;g=7352+(g+2<<2)|0;d=c[g>>2]|0;a=d+8|0;h=c[a>>2]|0;do if((e|0)!=(h|0)){if(h>>>0<(c[1832]|0)>>>0)ka();j=h+12|0;if((c[j>>2]|0)==(d|0)){c[j>>2]=e;c[g>>2]=h;m=c[1830]|0;break}else ka()}else{c[1828]=l&~(1<>2]=p|3;b=d+p|0;c[d+(p|4)>>2]=k|1;c[d+x>>2]=k;if(m){e=c[1833]|0;g=m>>>3;h=g<<1;f=7352+(h<<2)|0;j=c[1828]|0;g=1<>2]|0;if(h>>>0<(c[1832]|0)>>>0)ka();else{n=j;o=h}}else{c[1828]=j|g;n=7352+(h+2<<2)|0;o=f}c[n>>2]=e;c[o+12>>2]=e;c[e+8>>2]=o;c[e+12>>2]=f}c[1830]=k;c[1833]=b;x=a;i=L;return x|0}k=c[1829]|0;if(k){l=(k&0-k)+-1|0;w=l>>>12&16;l=l>>>w;v=l>>>5&8;l=l>>>v;x=l>>>2&4;l=l>>>x;j=l>>>1&2;l=l>>>j;m=l>>>1&1;m=c[7616+((v|w|x|j|m)+(l>>>m)<<2)>>2]|0;l=(c[m+4>>2]&-8)-p|0;j=m;while(1){d=c[j+16>>2]|0;if(!d){d=c[j+20>>2]|0;if(!d)break}j=(c[d+4>>2]&-8)-p|0;x=j>>>0>>0;l=x?j:l;j=d;m=x?d:m}k=c[1832]|0;if(m>>>0>>0)ka();b=m+p|0;if(m>>>0>=b>>>0)ka();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){e=0;break}}while(1){f=j+20|0;g=c[f>>2]|0;if(g){j=g;h=f;continue}f=j+16|0;g=c[f>>2]|0;if(!g)break;else{j=g;h=f}}if(h>>>0>>0)ka();else{c[h>>2]=0;e=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ka();j=f+12|0;if((c[j>>2]|0)!=(m|0))ka();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;e=g;break}else ka()}while(0);do if(a){j=c[m+28>>2]|0;h=7616+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=e;if(!e){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=e;else c[a+20>>2]=e;if(!e)break}h=c[1832]|0;if(e>>>0>>0)ka();c[e+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ka();else{c[e+16>>2]=j;c[j+24>>2]=e;break}while(0);f=c[m+20>>2]|0;if(f)if(f>>>0<(c[1832]|0)>>>0)ka();else{c[e+20>>2]=f;c[f+24>>2]=e;break}}while(0);if(l>>>0<16){x=l+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}else{c[m+4>>2]=p|3;c[m+(p|4)>>2]=l|1;c[m+(l+p)>>2]=l;d=c[1830]|0;if(d){e=c[1833]|0;g=d>>>3;h=g<<1;f=7352+(h<<2)|0;j=c[1828]|0;g=1<>2]|0;if(h>>>0<(c[1832]|0)>>>0)ka();else{r=j;q=h}}else{c[1828]=j|g;r=7352+(h+2<<2)|0;q=f}c[r>>2]=e;c[q+12>>2]=e;c[e+8>>2]=q;c[e+12>>2]=f}c[1830]=l;c[1833]=b}x=m+8|0;i=L;return x|0}}}else if(a>>>0<=4294967231){a=a+11|0;p=a&-8;m=c[1829]|0;if(m){h=0-p|0;a=a>>>8;if(a)if(p>>>0>16777215)l=31;else{q=(a+1048320|0)>>>16&8;r=a<>>16&4;r=r<>>16&2;l=14-(o|q|l)+(r<>>15)|0;l=p>>>(l+7|0)&1|l<<1}else l=0;j=c[7616+(l<<2)>>2]|0;a:do if(!j){a=0;k=0}else{if((l|0)==31)k=0;else k=25-(l>>>1)|0;f=h;a=0;e=p<>2]&-8;h=g-p|0;if(h>>>0>>0)if((g|0)==(p|0)){a=j;k=j;break a}else k=j;else h=f;r=c[j+20>>2]|0;j=c[j+(e>>>31<<2)+16>>2]|0;a=(r|0)==0|(r|0)==(j|0)?a:r;if(!j)break;else{f=h;e=e<<1}}}while(0);if((a|0)==0&(k|0)==0){a=2<>>12&16;r=r>>>n;m=r>>>5&8;r=r>>>m;o=r>>>2&4;r=r>>>o;q=r>>>1&2;r=r>>>q;a=r>>>1&1;a=c[7616+((m|n|o|q|a)+(r>>>a)<<2)>>2]|0}if(!a){n=h;m=k}else while(1){r=(c[a+4>>2]&-8)-p|0;j=r>>>0>>0;h=j?r:h;k=j?a:k;j=c[a+16>>2]|0;if(j){a=j;continue}a=c[a+20>>2]|0;if(!a){n=h;m=k;break}}if((m|0)!=0?n>>>0<((c[1830]|0)-p|0)>>>0:0){k=c[1832]|0;if(m>>>0>>0)ka();o=m+p|0;if(m>>>0>=o>>>0)ka();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){b=0;break}}while(1){f=j+20|0;g=c[f>>2]|0;if(g){j=g;h=f;continue}f=j+16|0;g=c[f>>2]|0;if(!g)break;else{j=g;h=f}}if(h>>>0>>0)ka();else{c[h>>2]=0;b=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ka();j=f+12|0;if((c[j>>2]|0)!=(m|0))ka();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;b=g;break}else ka()}while(0);do if(a){j=c[m+28>>2]|0;h=7616+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=b;if(!b){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=b;else c[a+20>>2]=b;if(!b)break}h=c[1832]|0;if(b>>>0>>0)ka();c[b+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ka();else{c[b+16>>2]=j;c[j+24>>2]=b;break}while(0);j=c[m+20>>2]|0;if(j)if(j>>>0<(c[1832]|0)>>>0)ka();else{c[b+20>>2]=j;c[j+24>>2]=b;break}}while(0);b:do if(n>>>0>=16){c[m+4>>2]=p|3;c[m+(p|4)>>2]=n|1;c[m+(n+p)>>2]=n;j=n>>>3;if(n>>>0<256){g=j<<1;d=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(e>>>0>=(c[1832]|0)>>>0){t=f;u=e;break}ka()}while(0);c[t>>2]=o;c[u+12>>2]=o;c[m+(p+8)>>2]=u;c[m+(p+12)>>2]=d;break}d=n>>>8;if(d)if(n>>>0>16777215)f=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|w|f)+(x<>>15)|0;f=n>>>(f+7|0)&1|f<<1}else f=0;h=7616+(f<<2)|0;c[m+(p+28)>>2]=f;c[m+(p+20)>>2]=0;c[m+(p+16)>>2]=0;j=c[1829]|0;g=1<>2]=o;c[m+(p+24)>>2]=h;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break}j=c[h>>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;c:do if((c[j+4>>2]&-8|0)!=(n|0)){f=n<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(n|0)){v=h;break c}else{f=f<<1;j=h}}if(g>>>0<(c[1832]|0)>>>0)ka();else{c[g>>2]=o;c[m+(p+24)>>2]=j;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break b}}else v=j;while(0);b=v+8|0;d=c[b>>2]|0;x=c[1832]|0;if(v>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=o;c[b>>2]=o;c[m+(p+8)>>2]=d;c[m+(p+12)>>2]=v;c[m+(p+24)>>2]=0;break}else ka()}else{x=n+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}while(0);x=m+8|0;i=L;return x|0}}}else p=-1;while(0);k=c[1830]|0;if(k>>>0>=p>>>0){d=k-p|0;b=c[1833]|0;if(d>>>0>15){c[1833]=b+p;c[1830]=d;c[b+(p+4)>>2]=d|1;c[b+k>>2]=d;c[b+4>>2]=p|3}else{c[1830]=0;c[1833]=0;c[b+4>>2]=k|3;x=b+(k+4)|0;c[x>>2]=c[x>>2]|1}x=b+8|0;i=L;return x|0}k=c[1831]|0;if(k>>>0>p>>>0){w=k-p|0;c[1831]=w;x=c[1834]|0;c[1834]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}do if(!(c[1946]|0)){k=ua(30)|0;if(!(k+-1&k)){c[1948]=k;c[1947]=k;c[1949]=-1;c[1950]=-1;c[1951]=0;c[1939]=0;c[1946]=(ta(0)|0)&-16^1431655768;break}else ka()}while(0);l=p+48|0;g=c[1948]|0;f=p+47|0;h=g+f|0;g=0-g|0;m=h&g;if(m>>>0<=p>>>0){x=0;i=L;return x|0}a=c[1938]|0;if((a|0)!=0?(u=c[1936]|0,v=u+m|0,v>>>0<=u>>>0|v>>>0>a>>>0):0){x=0;i=L;return x|0}d:do if(!(c[1939]&4)){j=c[1834]|0;e:do if(j){a=7760|0;while(1){k=c[a>>2]|0;if(k>>>0<=j>>>0?(s=a+4|0,(k+(c[s>>2]|0)|0)>>>0>j>>>0):0)break;a=c[a+8>>2]|0;if(!a){A=181;break e}}if(a){k=h-(c[1831]|0)&g;if(k>>>0<2147483647){j=ma(k|0)|0;if((j|0)==((c[a>>2]|0)+(c[s>>2]|0)|0))A=190;else A=191}else k=0}else A=181}else A=181;while(0);do if((A|0)==181){j=ma(0)|0;if((j|0)!=(-1|0)){a=j;k=c[1947]|0;h=k+-1|0;if(!(h&a))k=m;else k=m-a+(h+a&0-k)|0;a=c[1936]|0;h=a+k|0;if(k>>>0>p>>>0&k>>>0<2147483647){v=c[1938]|0;if((v|0)!=0?h>>>0<=a>>>0|h>>>0>v>>>0:0){k=0;break}h=ma(k|0)|0;if((h|0)==(j|0))A=190;else{j=h;A=191}}else k=0}else k=0}while(0);f:do if((A|0)==190){if((j|0)!=(-1|0)){w=j;s=k;A=201;break d}}else if((A|0)==191){a=0-k|0;do if((j|0)!=(-1|0)&k>>>0<2147483647&l>>>0>k>>>0?(d=c[1948]|0,d=f-k+d&0-d,d>>>0<2147483647):0)if((ma(d|0)|0)==(-1|0)){ma(a|0)|0;k=0;break f}else{k=d+k|0;break}while(0);if((j|0)==(-1|0))k=0;else{w=j;s=k;A=201;break d}}while(0);c[1939]=c[1939]|4;A=198}else{k=0;A=198}while(0);if((((A|0)==198?m>>>0<2147483647:0)?(w=ma(m|0)|0,x=ma(0)|0,(w|0)!=(-1|0)&(x|0)!=(-1|0)&w>>>0>>0):0)?(z=x-w|0,y=z>>>0>(p+40|0)>>>0,y):0){s=y?z:k;A=201}if((A|0)==201){j=(c[1936]|0)+s|0;c[1936]=j;if(j>>>0>(c[1937]|0)>>>0)c[1937]=j;o=c[1834]|0;g:do if(o){f=7760|0;while(1){k=c[f>>2]|0;g=f+4|0;j=c[g>>2]|0;if((w|0)==(k+j|0)){A=213;break}h=c[f+8>>2]|0;if(!h)break;else f=h}if(((A|0)==213?(c[f+12>>2]&8|0)==0:0)?o>>>0>=k>>>0&o>>>0>>0:0){c[g>>2]=j+s;d=(c[1831]|0)+s|0;b=o+8|0;if(!(b&7))b=0;else b=0-b&7;x=d-b|0;c[1834]=o+b;c[1831]=x;c[o+(b+4)>>2]=x|1;c[o+(d+4)>>2]=40;c[1835]=c[1950];break}k=c[1832]|0;if(w>>>0>>0){c[1832]=w;k=w}h=w+s|0;g=7760|0;while(1){if((c[g>>2]|0)==(h|0)){A=223;break}j=c[g+8>>2]|0;if(!j)break;else g=j}if((A|0)==223?(c[g+12>>2]&8|0)==0:0){c[g>>2]=w;j=g+4|0;c[j>>2]=(c[j>>2]|0)+s;j=w+8|0;if(!(j&7))r=0;else r=0-j&7;j=w+(s+8)|0;if(!(j&7))b=0;else b=0-j&7;j=w+(b+s)|0;q=r+p|0;n=w+q|0;d=j-(w+r)-p|0;c[w+(r+4)>>2]=p|3;h:do if((j|0)!=(o|0)){if((j|0)==(c[1833]|0)){x=(c[1830]|0)+d|0;c[1830]=x;c[1833]=n;c[w+(q+4)>>2]=x|1;c[w+(x+q)>>2]=x;break}l=s+4|0;h=c[w+(l+b)>>2]|0;if((h&3|0)==1){m=h&-8;e=h>>>3;i:do if(h>>>0>=256){a=c[w+((b|24)+s)>>2]|0;g=c[w+(s+12+b)>>2]|0;do if((g|0)==(j|0)){g=b|16;f=w+(l+g)|0;h=c[f>>2]|0;if(!h){g=w+(g+s)|0;h=c[g>>2]|0;if(!h){H=0;break}}else g=f;while(1){e=h+20|0;f=c[e>>2]|0;if(f){h=f;g=e;continue}e=h+16|0;f=c[e>>2]|0;if(!f)break;else{h=f;g=e}}if(g>>>0>>0)ka();else{c[g>>2]=0;H=h;break}}else{f=c[w+((b|8)+s)>>2]|0;if(f>>>0>>0)ka();k=f+12|0;if((c[k>>2]|0)!=(j|0))ka();h=g+8|0;if((c[h>>2]|0)==(j|0)){c[k>>2]=g;c[h>>2]=f;H=g;break}else ka()}while(0);if(!a)break;k=c[w+(s+28+b)>>2]|0;h=7616+(k<<2)|0;do if((j|0)!=(c[h>>2]|0)){if(a>>>0<(c[1832]|0)>>>0)ka();k=a+16|0;if((c[k>>2]|0)==(j|0))c[k>>2]=H;else c[a+20>>2]=H;if(!H)break i}else{c[h>>2]=H;if(H)break;c[1829]=c[1829]&~(1<>>0>>0)ka();c[H+24>>2]=a;j=b|16;k=c[w+(j+s)>>2]|0;do if(k)if(k>>>0>>0)ka();else{c[H+16>>2]=k;c[k+24>>2]=H;break}while(0);j=c[w+(l+j)>>2]|0;if(!j)break;if(j>>>0<(c[1832]|0)>>>0)ka();else{c[H+20>>2]=j;c[j+24>>2]=H;break}}else{g=c[w+((b|8)+s)>>2]|0;f=c[w+(s+12+b)>>2]|0;h=7352+(e<<1<<2)|0;do if((g|0)!=(h|0)){if(g>>>0>>0)ka();if((c[g+12>>2]|0)==(j|0))break;ka()}while(0);if((f|0)==(g|0)){c[1828]=c[1828]&~(1<>>0>>0)ka();k=f+8|0;if((c[k>>2]|0)==(j|0)){D=k;break}ka()}while(0);c[g+12>>2]=f;c[D>>2]=g}while(0);j=w+((m|b)+s)|0;k=m+d|0}else k=d;j=j+4|0;c[j>>2]=c[j>>2]&-2;c[w+(q+4)>>2]=k|1;c[w+(k+q)>>2]=k;j=k>>>3;if(k>>>0<256){g=j<<1;f=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(h>>>0>=(c[1832]|0)>>>0){I=j;J=h;break}ka()}while(0);c[I>>2]=n;c[J+12>>2]=n;c[w+(q+8)>>2]=J;c[w+(q+12)>>2]=f;break}d=k>>>8;do if(!d)f=0;else{if(k>>>0>16777215){f=31;break}v=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|v|f)+(x<>>15)|0;f=k>>>(f+7|0)&1|f<<1}while(0);h=7616+(f<<2)|0;c[w+(q+28)>>2]=f;c[w+(q+20)>>2]=0;c[w+(q+16)>>2]=0;j=c[1829]|0;g=1<>2]=n;c[w+(q+24)>>2]=h;c[w+(q+12)>>2]=n;c[w+(q+8)>>2]=n;break}j=c[h>>2]|0;if((f|0)==31)h=0;else h=25-(f>>>1)|0;j:do if((c[j+4>>2]&-8|0)!=(k|0)){f=k<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(k|0)){K=h;break j}else{f=f<<1;j=h}}if(g>>>0<(c[1832]|0)>>>0)ka();else{c[g>>2]=n;c[w+(q+24)>>2]=j;c[w+(q+12)>>2]=n;c[w+(q+8)>>2]=n;break h}}else K=j;while(0);b=K+8|0;d=c[b>>2]|0;x=c[1832]|0;if(K>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=n;c[b>>2]=n;c[w+(q+8)>>2]=d;c[w+(q+12)>>2]=K;c[w+(q+24)>>2]=0;break}else ka()}else{x=(c[1831]|0)+d|0;c[1831]=x;c[1834]=n;c[w+(q+4)>>2]=x|1}while(0);x=w+(r|8)|0;i=L;return x|0}j=7760|0;while(1){h=c[j>>2]|0;if(h>>>0<=o>>>0?(B=c[j+4>>2]|0,C=h+B|0,C>>>0>o>>>0):0)break;j=c[j+8>>2]|0}j=h+(B+-39)|0;if(!(j&7))j=0;else j=0-j&7;g=h+(B+-47+j)|0;g=g>>>0<(o+16|0)>>>0?o:g;h=g+8|0;j=w+8|0;if(!(j&7))j=0;else j=0-j&7;f=s+-40-j|0;c[1834]=w+j;c[1831]=f;c[w+(j+4)>>2]=f|1;c[w+(s+-36)>>2]=40;c[1835]=c[1950];c[g+4>>2]=27;c[h+0>>2]=c[1940];c[h+4>>2]=c[1941];c[h+8>>2]=c[1942];c[h+12>>2]=c[1943];c[1940]=w;c[1941]=s;c[1943]=0;c[1942]=h;f=g+28|0;c[f>>2]=7;if((g+32|0)>>>0>>0)do{x=f;f=f+4|0;c[f>>2]=7}while((x+8|0)>>>0>>0);if((g|0)!=(o|0)){k=g-o|0;j=o+(k+4)|0;c[j>>2]=c[j>>2]&-2;c[o+4>>2]=k|1;c[o+k>>2]=k;j=k>>>3;if(k>>>0<256){g=j<<1;f=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(b>>>0>=(c[1832]|0)>>>0){E=d;F=b;break}ka()}while(0);c[E>>2]=o;c[F+12>>2]=o;c[o+8>>2]=F;c[o+12>>2]=f;break}d=k>>>8;if(d)if(k>>>0>16777215)g=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;g=14-(v|w|g)+(x<>>15)|0;g=k>>>(g+7|0)&1|g<<1}else g=0;h=7616+(g<<2)|0;c[o+28>>2]=g;c[o+20>>2]=0;c[o+16>>2]=0;e=c[1829]|0;j=1<>2]=o;c[o+24>>2]=h;c[o+12>>2]=o;c[o+8>>2]=o;break}e=c[h>>2]|0;if((g|0)==31)d=0;else d=25-(g>>>1)|0;k:do if((c[e+4>>2]&-8|0)!=(k|0)){j=k<>>31<<2)+16|0;d=c[h>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(k|0)){G=d;break k}else{j=j<<1;e=d}}if(h>>>0<(c[1832]|0)>>>0)ka();else{c[h>>2]=o;c[o+24>>2]=e;c[o+12>>2]=o;c[o+8>>2]=o;break g}}else G=e;while(0);b=G+8|0;d=c[b>>2]|0;x=c[1832]|0;if(G>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=o;c[b>>2]=o;c[o+8>>2]=d;c[o+12>>2]=G;c[o+24>>2]=0;break}else ka()}}else{x=c[1832]|0;if((x|0)==0|w>>>0>>0)c[1832]=w;c[1940]=w;c[1941]=s;c[1943]=0;c[1837]=c[1946];c[1836]=-1;b=0;do{x=b<<1;v=7352+(x<<2)|0;c[7352+(x+3<<2)>>2]=v;c[7352+(x+2<<2)>>2]=v;b=b+1|0}while((b|0)!=32);b=w+8|0;if(!(b&7))b=0;else b=0-b&7;x=s+-40-b|0;c[1834]=w+b;c[1831]=x;c[w+(b+4)>>2]=x|1;c[w+(s+-36)>>2]=40;c[1835]=c[1950]}while(0);b=c[1831]|0;if(b>>>0>p>>>0){w=b-p|0;c[1831]=w;x=c[1834]|0;c[1834]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}}c[(va()|0)>>2]=12;x=0;i=L;return x|0}function kd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=i;if(!a){i=w;return}f=a+-8|0;h=c[1832]|0;if(f>>>0>>0)ka();g=c[a+-4>>2]|0;e=g&3;if((e|0)==1)ka();q=g&-8;r=a+(q+-8)|0;do if(!(g&1)){g=c[f>>2]|0;if(!e){i=w;return}j=-8-g|0;m=a+j|0;n=g+q|0;if(m>>>0>>0)ka();if((m|0)==(c[1833]|0)){f=a+(q+-4)|0;g=c[f>>2]|0;if((g&3|0)!=3){v=m;l=n;break}c[1830]=n;c[f>>2]=g&-2;c[a+(j+4)>>2]=n|1;c[r>>2]=n;i=w;return}d=g>>>3;if(g>>>0<256){e=c[a+(j+8)>>2]|0;f=c[a+(j+12)>>2]|0;g=7352+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0>>0)ka();if((c[e+12>>2]|0)!=(m|0))ka()}if((f|0)==(e|0)){c[1828]=c[1828]&~(1<>>0>>0)ka();g=f+8|0;if((c[g>>2]|0)==(m|0))b=g;else ka()}else b=f+8|0;c[e+12>>2]=f;c[b>>2]=e;v=m;l=n;break}b=c[a+(j+24)>>2]|0;e=c[a+(j+12)>>2]|0;do if((e|0)==(m|0)){f=a+(j+20)|0;g=c[f>>2]|0;if(!g){f=a+(j+16)|0;g=c[f>>2]|0;if(!g){k=0;break}}while(1){d=g+20|0;e=c[d>>2]|0;if(e){g=e;f=d;continue}d=g+16|0;e=c[d>>2]|0;if(!e)break;else{g=e;f=d}}if(f>>>0>>0)ka();else{c[f>>2]=0;k=g;break}}else{d=c[a+(j+8)>>2]|0;if(d>>>0>>0)ka();g=d+12|0;if((c[g>>2]|0)!=(m|0))ka();f=e+8|0;if((c[f>>2]|0)==(m|0)){c[g>>2]=e;c[f>>2]=d;k=e;break}else ka()}while(0);if(b){g=c[a+(j+28)>>2]|0;f=7616+(g<<2)|0;if((m|0)==(c[f>>2]|0)){c[f>>2]=k;if(!k){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();g=b+16|0;if((c[g>>2]|0)==(m|0))c[g>>2]=k;else c[b+20>>2]=k;if(!k){v=m;l=n;break}}f=c[1832]|0;if(k>>>0>>0)ka();c[k+24>>2]=b;g=c[a+(j+16)>>2]|0;do if(g)if(g>>>0>>0)ka();else{c[k+16>>2]=g;c[g+24>>2]=k;break}while(0);g=c[a+(j+20)>>2]|0;if(g)if(g>>>0<(c[1832]|0)>>>0)ka();else{c[k+20>>2]=g;c[g+24>>2]=k;v=m;l=n;break}else{v=m;l=n}}else{v=m;l=n}}else{v=f;l=q}while(0);if(v>>>0>=r>>>0)ka();g=a+(q+-4)|0;f=c[g>>2]|0;if(!(f&1))ka();if(!(f&2)){if((r|0)==(c[1834]|0)){m=(c[1831]|0)+l|0;c[1831]=m;c[1834]=v;c[v+4>>2]=m|1;if((v|0)!=(c[1833]|0)){i=w;return}c[1833]=0;c[1830]=0;i=w;return}if((r|0)==(c[1833]|0)){m=(c[1830]|0)+l|0;c[1830]=m;c[1833]=v;c[v+4>>2]=m|1;c[v+m>>2]=m;i=w;return}h=(f&-8)+l|0;d=f>>>3;do if(f>>>0>=256){b=c[a+(q+16)>>2]|0;g=c[a+(q|4)>>2]|0;do if((g|0)==(r|0)){f=a+(q+12)|0;g=c[f>>2]|0;if(!g){f=a+(q+8)|0;g=c[f>>2]|0;if(!g){p=0;break}}while(1){d=g+20|0;e=c[d>>2]|0;if(e){g=e;f=d;continue}d=g+16|0;e=c[d>>2]|0;if(!e)break;else{g=e;f=d}}if(f>>>0<(c[1832]|0)>>>0)ka();else{c[f>>2]=0;p=g;break}}else{f=c[a+q>>2]|0;if(f>>>0<(c[1832]|0)>>>0)ka();e=f+12|0;if((c[e>>2]|0)!=(r|0))ka();d=g+8|0;if((c[d>>2]|0)==(r|0)){c[e>>2]=g;c[d>>2]=f;p=g;break}else ka()}while(0);if(b){g=c[a+(q+20)>>2]|0;f=7616+(g<<2)|0;if((r|0)==(c[f>>2]|0)){c[f>>2]=p;if(!p){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();g=b+16|0;if((c[g>>2]|0)==(r|0))c[g>>2]=p;else c[b+20>>2]=p;if(!p)break}g=c[1832]|0;if(p>>>0>>0)ka();c[p+24>>2]=b;f=c[a+(q+8)>>2]|0;do if(f)if(f>>>0>>0)ka();else{c[p+16>>2]=f;c[f+24>>2]=p;break}while(0);d=c[a+(q+12)>>2]|0;if(d)if(d>>>0<(c[1832]|0)>>>0)ka();else{c[p+20>>2]=d;c[d+24>>2]=p;break}}}else{e=c[a+q>>2]|0;f=c[a+(q|4)>>2]|0;g=7352+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0<(c[1832]|0)>>>0)ka();if((c[e+12>>2]|0)!=(r|0))ka()}if((f|0)==(e|0)){c[1828]=c[1828]&~(1<>>0<(c[1832]|0)>>>0)ka();g=f+8|0;if((c[g>>2]|0)==(r|0))o=g;else ka()}else o=f+8|0;c[e+12>>2]=f;c[o>>2]=e}while(0);c[v+4>>2]=h|1;c[v+h>>2]=h;if((v|0)==(c[1833]|0)){c[1830]=h;i=w;return}else g=h}else{c[g>>2]=f&-2;c[v+4>>2]=l|1;c[v+l>>2]=l;g=l}e=g>>>3;if(g>>>0<256){f=e<<1;g=7352+(f<<2)|0;d=c[1828]|0;e=1<>2]|0;if(b>>>0<(c[1832]|0)>>>0)ka();else{s=d;t=b}}else{c[1828]=d|e;s=7352+(f+2<<2)|0;t=g}c[s>>2]=v;c[t+12>>2]=v;c[v+8>>2]=t;c[v+12>>2]=g;i=w;return}d=g>>>8;if(d)if(g>>>0>16777215)f=31;else{l=(d+1048320|0)>>>16&8;m=d<>>16&4;m=m<>>16&2;f=14-(k|l|f)+(m<>>15)|0;f=g>>>(f+7|0)&1|f<<1}else f=0;b=7616+(f<<2)|0;c[v+28>>2]=f;c[v+20>>2]=0;c[v+16>>2]=0;d=c[1829]|0;e=1<>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;b:do if((c[b+4>>2]&-8|0)!=(g|0)){f=g<>>31<<2)+16|0;d=c[e>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(g|0)){u=d;break b}else{f=f<<1;b=d}}if(e>>>0<(c[1832]|0)>>>0)ka();else{c[e>>2]=v;c[v+24>>2]=b;c[v+12>>2]=v;c[v+8>>2]=v;break a}}else u=b;while(0);d=u+8|0;b=c[d>>2]|0;m=c[1832]|0;if(u>>>0>=m>>>0&b>>>0>=m>>>0){c[b+12>>2]=v;c[d>>2]=v;c[v+8>>2]=b;c[v+12>>2]=u;c[v+24>>2]=0;break}else ka()}else{c[1829]=d|e;c[b>>2]=v;c[v+24>>2]=b;c[v+12>>2]=v;c[v+8>>2]=v}while(0);m=(c[1836]|0)+-1|0;c[1836]=m;if(!m)b=7768|0;else{i=w;return}while(1){b=c[b>>2]|0;if(!b)break;else b=b+8|0}c[1836]=-1;i=w;return}function ld(){}function md(b){b=b|0;var c=0;c=b;while(a[c>>0]|0)c=c+1|0;return c-b|0}function nd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;h=b&3;i=d|d<<8|d<<16|d<<24;g=f&~3;if(h){h=b+4-h|0;while((b|0)<(h|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(g|0)){c[b>>2]=i;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function od(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return pa(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function pd(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;xa[a&3](b|0,c|0,d|0,e|0,f|0)}function qd(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;_(0)} + +// EMSCRIPTEN_END_FUNCS +var xa=[qd,fc,ec,qd];return{_strlen:md,_free:kd,_broadwayGetMajorVersion:dd,_get_h264bsdClip:Lb,_broadwayExit:cd,_memset:nd,_broadwayCreateStream:Zc,_malloc:jd,_memcpy:od,_broadwayGetMinorVersion:ed,_broadwayPlayStream:$c,_broadwaySetStreamLength:_c,_broadwayInit:ad,runPostSets:ld,stackAlloc:ya,stackSave:za,stackRestore:Aa,setThrew:Ba,setTempRet0:Ea,getTempRet0:Fa,dynCall_viiiii:pd}}) + + +// EMSCRIPTEN_END_ASM +(p.Xc,p.Yc,Q),Bb=p._strlen=$._strlen,Ea=p._free=$._free;p._broadwayGetMajorVersion=$._broadwayGetMajorVersion;p._get_h264bsdClip=$._get_h264bsdClip;p._broadwayExit=$._broadwayExit;var Gb=p._memset=$._memset;p._broadwayCreateStream=$._broadwayCreateStream;var Ca=p._malloc=$._malloc,gc=p._memcpy=$._memcpy; +p._broadwayGetMinorVersion=$._broadwayGetMinorVersion;p._broadwayPlayStream=$._broadwayPlayStream;p._broadwaySetStreamLength=$._broadwaySetStreamLength;p._broadwayInit=$._broadwayInit;p.runPostSets=$.runPostSets;p.dynCall_viiiii=$.dynCall_viiiii;z.pb=$.stackAlloc;z.Tb=$.stackSave;z.Sb=$.stackRestore;z.Yd=$.setTempRet0;z.xd=$.getTempRet0; +if(T)if("function"===typeof p.locateFile?T=p.locateFile(T):p.memoryInitializerPrefixURL&&(T=p.memoryInitializerPrefixURL+T),t||da){var hc=p.readBinary(T);N.set(hc,Ia)}else Ya(),yb(T,function(a){N.set(a,Ia);Za()},function(){d("could not load memory initializer "+T)});function ia(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}ia.prototype=Error();var ic,jc=k,Xa=function kc(){!p.calledRun&&lc&&mc();p.calledRun||(Xa=kc)}; +p.callMain=p.ag=function(a){function b(){for(var a=0;3>a;a++)e.push(0)}w(0==S,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");w(0==Oa.length,"cannot call main when preRun functions remain to be called");a=a||[];Sa||(Sa=i,Na(R));var c=a.length+1,e=[M(Va(p.thisProgram),"i8",0)];b();for(var f=0;f y ? y : z); + } + + function OptimizedGetBoundaryStrengthsA($mb, $bS) { + var $totalCoeff = $mb + 28; + + var tc0 = HEAP16[$totalCoeff + 0 >> 1]; + var tc1 = HEAP16[$totalCoeff + 2 >> 1]; + var tc2 = HEAP16[$totalCoeff + 4 >> 1]; + var tc3 = HEAP16[$totalCoeff + 6 >> 1]; + var tc4 = HEAP16[$totalCoeff + 8 >> 1]; + var tc5 = HEAP16[$totalCoeff + 10 >> 1]; + var tc6 = HEAP16[$totalCoeff + 12 >> 1]; + var tc7 = HEAP16[$totalCoeff + 14 >> 1]; + var tc8 = HEAP16[$totalCoeff + 16 >> 1]; + var tc9 = HEAP16[$totalCoeff + 18 >> 1]; + var tc10 = HEAP16[$totalCoeff + 20 >> 1]; + var tc11 = HEAP16[$totalCoeff + 22 >> 1]; + var tc12 = HEAP16[$totalCoeff + 24 >> 1]; + var tc13 = HEAP16[$totalCoeff + 26 >> 1]; + var tc14 = HEAP16[$totalCoeff + 28 >> 1]; + var tc15 = HEAP16[$totalCoeff + 30 >> 1]; + + HEAP32[$bS + 32 >> 2] = tc2 || tc0 ? 2 : 0; + HEAP32[$bS + 40 >> 2] = tc3 || tc1 ? 2 : 0; + HEAP32[$bS + 48 >> 2] = tc6 || tc4 ? 2 : 0; + HEAP32[$bS + 56 >> 2] = tc7 || tc5 ? 2 : 0; + HEAP32[$bS + 64 >> 2] = tc8 || tc2 ? 2 : 0; + HEAP32[$bS + 72 >> 2] = tc9 || tc3 ? 2 : 0; + HEAP32[$bS + 80 >> 2] = tc12 || tc6 ? 2 : 0; + HEAP32[$bS + 88 >> 2] = tc13 || tc7 ? 2 : 0; + HEAP32[$bS + 96 >> 2] = tc10 || tc8 ? 2 : 0; + HEAP32[$bS + 104 >> 2] = tc11 || tc9 ? 2 : 0; + HEAP32[$bS + 112 >> 2] = tc14 || tc12 ? 2 : 0; + HEAP32[$bS + 120 >> 2] = tc15 || tc13 ? 2 : 0; + + HEAP32[$bS + 12 >> 2] = tc1 || tc0 ? 2 : 0; + HEAP32[$bS + 20 >> 2] = tc4 || tc1 ? 2 : 0; + HEAP32[$bS + 28 >> 2] = tc5 || tc4 ? 2 : 0; + HEAP32[$bS + 44 >> 2] = tc3 || tc2 ? 2 : 0; + HEAP32[$bS + 52 >> 2] = tc6 || tc3 ? 2 : 0; + HEAP32[$bS + 60 >> 2] = tc7 || tc6 ? 2 : 0; + HEAP32[$bS + 76 >> 2] = tc9 || tc8 ? 2 : 0; + HEAP32[$bS + 84 >> 2] = tc12 || tc9 ? 2 : 0; + HEAP32[$bS + 92 >> 2] = tc13 || tc12 ? 2 : 0; + HEAP32[$bS + 108 >> 2] = tc11 || tc10 ? 2 : 0; + HEAP32[$bS + 116 >> 2] = tc14 || tc11 ? 2 : 0; + HEAP32[$bS + 124 >> 2] = tc15 || tc14 ? 2 : 0; + } + + function OptimizedFilterVerLumaEdge ($data, bS, $thresholds, imageWidth) { + var delta, tc, tmp; + var p0, q0, p1, q1, p2, q2; + var tmpFlag; + var $clp = _h264bsdClip + 512; + var alpha = HEAP32[$thresholds + 4 >> 2]; + var beta = HEAP32[$thresholds + 8 >> 2]; + var val; + + if (bS < 4) { + tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255; + for (var i = 4; i > 0; i--) { + p1 = HEAPU8[$data + -2] & 255; + p0 = HEAPU8[$data + -1] & 255; + q0 = HEAPU8[$data] & 255; + q1 = HEAPU8[$data + 1] & 255; + if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) { + p2 = HEAPU8[$data - 3] & 255; + if (Math.abs(p2 - p0) < beta) { + val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; + HEAP8[$data - 2] = p1 + clip(-tc, tc, val); + tmp++; + } + + q2 = HEAPU8[$data + 2] & 255; + if (Math.abs(q2 - q0) < beta) { + val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; + HEAP8[$data + 1] = (q1 + clip(-tc, tc, val)); + tmp++; + } + + val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); + delta = clip(-tmp, tmp, val); + + p0 = HEAPU8[$clp + (p0 + delta)] & 255; + q0 = HEAPU8[$clp + (q0 - delta)] & 255; + tmp = tc; + HEAP8[$data - 1] = p0; + HEAP8[$data] = q0; + + $data += imageWidth; + } + } + } else { + OriginalFilterVerLumaEdge($data, bS, $thresholds, imageWidth); + } + } + + /** + * Filter all four successive horizontal 4-pixel luma edges. This can be done when bS is equal to all four edges. + */ + function OptimizedFilterHorLuma ($data, bS, $thresholds, imageWidth) { + var delta, tc, tmp; + var p0, q0, p1, q1, p2, q2; + var tmpFlag; + var $clp = _h264bsdClip + 512; + var alpha = HEAP32[$thresholds + 4 >> 2]; + var beta = HEAP32[$thresholds + 8 >> 2]; + var val; + + if (bS < 4) { + tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255; + for (var i = 16; i > 0; i--) { + p1 = HEAPU8[$data + (-imageWidth << 1)] & 255; + p0 = HEAPU8[$data + -imageWidth] & 255; + q0 = HEAPU8[$data] & 255; + q1 = HEAPU8[$data + imageWidth] & 255; + + if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) { + p2 = HEAPU8[$data + (-imageWidth * 3)] & 255; + if (Math.abs(p2 - p0) < beta) { + val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; + HEAP8[$data + (-imageWidth << 1)] = p1 + clip(-tc, tc, val); + tmp++; + } + + q2 = HEAPU8[$data + (imageWidth << 2)] & 255; + if (Math.abs(q2 - q0) < beta) { + val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; + HEAP8[$data + imageWidth] = (q1 + clip(-tc, tc, val)); + tmp++; + } + + val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); + delta = clip(-tmp, tmp, val); + + p0 = HEAPU8[$clp + (p0 + delta)] & 255; + q0 = HEAPU8[$clp + (q0 - delta)] & 255; + tmp = tc; + HEAP8[$data - imageWidth] = p0; + HEAP8[$data] = q0; + + $data ++; + } + } + } else { + OriginalFilterHorLuma($data, bS, $thresholds, imageWidth); + } + } + }; + + + Broadway.prototype = { + configure: function (config) { + // patchOptimizations(config, patches); + console.info("Broadway Configured: " + JSON.stringify(config)); + } + + }; + + + + + /* + + asm.js implementation of a yuv to rgb convertor + provided by @soliton4 + + based on + http://www.wordsaretoys.com/2013/10/18/making-yuv-conversion-a-little-faster/ + + */ + + + // factory to create asm.js yuv -> rgb convertor for a given resolution + var asmInstances = {}; + var getAsm = function(parWidth, parHeight){ + var idStr = "" + parWidth + "x" + parHeight; + if (asmInstances[idStr]){ + return asmInstances[idStr]; + }; + + var lumaSize = parWidth * parHeight; + var chromaSize = (lumaSize|0) >> 2; + + var inpSize = lumaSize + chromaSize + chromaSize; + var outSize = parWidth * parHeight * 4; + var cacheSize = Math.pow(2, 24) * 4; + var size = inpSize + outSize + cacheSize; + + var chunkSize = Math.pow(2, 24); + var heapSize = chunkSize; + while (heapSize < size){ + heapSize += chunkSize; + }; + var heap = new ArrayBuffer(heapSize); + + var res = asmFactory(global, {}, heap); + res.init(parWidth, parHeight); + asmInstances[idStr] = res; + + res.heap = heap; + res.out = new Uint8Array(heap, 0, outSize); + res.inp = new Uint8Array(heap, outSize, inpSize); + res.outSize = outSize; + + return res; + }; + + + function asmFactory(stdlib, foreign, heap) { + "use asm"; + + var imul = stdlib.Math.imul; + var min = stdlib.Math.min; + var max = stdlib.Math.max; + var pow = stdlib.Math.pow; + var out = new stdlib.Uint8Array(heap); + var out32 = new stdlib.Uint32Array(heap); + var inp = new stdlib.Uint8Array(heap); + var mem = new stdlib.Uint8Array(heap); + var mem32 = new stdlib.Uint32Array(heap); + + // for double algo + /*var vt = 1.370705; + var gt = 0.698001; + var gt2 = 0.337633; + var bt = 1.732446;*/ + + var width = 0; + var height = 0; + var lumaSize = 0; + var chromaSize = 0; + var inpSize = 0; + var outSize = 0; + + var inpStart = 0; + var outStart = 0; + + var widthFour = 0; + + var cacheStart = 0; + + + function init(parWidth, parHeight){ + parWidth = parWidth|0; + parHeight = parHeight|0; + + var i = 0; + var s = 0; + + width = parWidth; + widthFour = imul(parWidth, 4)|0; + height = parHeight; + lumaSize = imul(width|0, height|0)|0; + chromaSize = (lumaSize|0) >> 2; + outSize = imul(imul(width, height)|0, 4)|0; + inpSize = ((lumaSize + chromaSize)|0 + chromaSize)|0; + + outStart = 0; + inpStart = (outStart + outSize)|0; + cacheStart = (inpStart + inpSize)|0; + + // initializing memory (to be on the safe side) + s = ~~(+pow(+2, +24)); + s = imul(s, 4)|0; + + for (i = 0|0; ((i|0) < (s|0))|0; i = (i + 4)|0){ + mem32[((cacheStart + i)|0) >> 2] = 0; + }; + }; + + function doit(){ + var ystart = 0; + var ustart = 0; + var vstart = 0; + + var y = 0; + var yn = 0; + var u = 0; + var v = 0; + + var o = 0; + + var line = 0; + var col = 0; + + var usave = 0; + var vsave = 0; + + var ostart = 0; + var cacheAdr = 0; + + ostart = outStart|0; + + ystart = inpStart|0; + ustart = (ystart + lumaSize|0)|0; + vstart = (ustart + chromaSize)|0; + + for (line = 0; (line|0) < (height|0); line = (line + 2)|0){ + usave = ustart; + vsave = vstart; + for (col = 0; (col|0) < (width|0); col = (col + 2)|0){ + y = inp[ystart >> 0]|0; + yn = inp[((ystart + width)|0) >> 0]|0; + + u = inp[ustart >> 0]|0; + v = inp[vstart >> 0]|0; + + cacheAdr = (((((y << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(y,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[ostart >> 2] = o; + + cacheAdr = (((((yn << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(yn,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[((ostart + widthFour)|0) >> 2] = o; + + //yuv2rgb5(y, u, v, ostart); + //yuv2rgb5(yn, u, v, (ostart + widthFour)|0); + ostart = (ostart + 4)|0; + + // next step only for y. u and v stay the same + ystart = (ystart + 1)|0; + y = inp[ystart >> 0]|0; + yn = inp[((ystart + width)|0) >> 0]|0; + + //yuv2rgb5(y, u, v, ostart); + cacheAdr = (((((y << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(y,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[ostart >> 2] = o; + + //yuv2rgb5(yn, u, v, (ostart + widthFour)|0); + cacheAdr = (((((yn << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(yn,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[((ostart + widthFour)|0) >> 2] = o; + ostart = (ostart + 4)|0; + + //all positions inc 1 + + ystart = (ystart + 1)|0; + ustart = (ustart + 1)|0; + vstart = (vstart + 1)|0; + }; + ostart = (ostart + widthFour)|0; + ystart = (ystart + width)|0; + + }; + + }; + + function yuv2rgbcalc(y, u, v){ + y = y|0; + u = u|0; + v = v|0; + + var r = 0; + var g = 0; + var b = 0; + + var o = 0; + + var a0 = 0; + var a1 = 0; + var a2 = 0; + var a3 = 0; + var a4 = 0; + + a0 = imul(1192, (y - 16)|0)|0; + a1 = imul(1634, (v - 128)|0)|0; + a2 = imul(832, (v - 128)|0)|0; + a3 = imul(400, (u - 128)|0)|0; + a4 = imul(2066, (u - 128)|0)|0; + + r = (((a0 + a1)|0) >> 10)|0; + g = (((((a0 - a2)|0) - a3)|0) >> 10)|0; + b = (((a0 + a4)|0) >> 10)|0; + + if ((((r & 255)|0) != (r|0))|0){ + r = min(255, max(0, r|0)|0)|0; + }; + if ((((g & 255)|0) != (g|0))|0){ + g = min(255, max(0, g|0)|0)|0; + }; + if ((((b & 255)|0) != (b|0))|0){ + b = min(255, max(0, b|0)|0)|0; + }; + + o = 255; + o = (o << 8)|0; + o = (o + b)|0; + o = (o << 8)|0; + o = (o + g)|0; + o = (o << 8)|0; + o = (o + r)|0; + + return o|0; + + }; + + + + return { + init: init, + doit: doit + }; + }; + + + /* + potential worker initialization + + */ + + + if (typeof self != "undefined"){ + var isWorker = false; + var decoder; + var reuseMemory = false; + + var memAr = []; + var getMem = function(length){ + if (memAr.length){ + var u = memAr.shift(); + while (u && u.byteLength !== length){ + u = memAr.shift(); + }; + if (u){ + return u; + }; + }; + return new ArrayBuffer(length); + }; + + self.addEventListener('message', function(e) { + + if (isWorker){ + if (reuseMemory){ + if (e.data.reuse){ + memAr.push(e.data.reuse); + }; + }; + if (e.data.buf){ + decoder.decode(new Uint8Array(e.data.buf, e.data.offset || 0, e.data.length), e.data.info); + }; + + }else{ + if (e.data && e.data.type === "Broadway.js - Worker init"){ + isWorker = true; + decoder = new Broadway(e.data.options); + + if (e.data.options.reuseMemory){ + reuseMemory = true; + decoder.onPictureDecoded = function (buffer, width, height, infos) { + + //var buf = getMem(); + + // buffer needs to be copied because we give up ownership + var copyU8 = new Uint8Array(getMem(buffer.length)); + copyU8.set( buffer, 0, buffer.length ); + + postMessage({ + buf: copyU8.buffer, + length: buffer.length, + width: width, + height: height, + infos: infos + }, [copyU8.buffer]); // 2nd parameter is used to indicate transfer of ownership + + }; + + }else{ + decoder.onPictureDecoded = function (buffer, width, height, infos) { + if (buffer) { + buffer = new Uint8Array(buffer); + }; + + // buffer needs to be copied because we give up ownership + var copyU8 = new Uint8Array(buffer.length); + copyU8.set( buffer, 0, buffer.length ); + + postMessage({ + buf: copyU8.buffer, + length: buffer.length, + width: width, + height: height, + infos: infos + }, [copyU8.buffer]); // 2nd parameter is used to indicate transfer of ownership + + }; + }; + postMessage({ consoleLog: "broadway worker initialized" }); + }; + }; + + + }, false); + }; + + Broadway.nowValue = nowValue; + + return Broadway; + + })(); + + +})); + + +}).call(this,"/dvp\\node_modules\\h264-live-player\\vendor\\broadway") +},{}],5:[function(require,module,exports){ +"use strict"; +var assert = require('../utils/assert'); + + +function Program(gl) { + this.gl = gl; + this.program = this.gl.createProgram(); +} + +Program.prototype = { + attach: function (shader) { + this.gl.attachShader(this.program, shader.shader); + }, + link: function () { + this.gl.linkProgram(this.program); + // If creating the shader program failed, alert. + assert(this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS), + "Unable to initialize the shader program."); + }, + use: function () { + this.gl.useProgram(this.program); + }, + getAttributeLocation: function(name) { + return this.gl.getAttribLocation(this.program, name); + }, + setMatrixUniform: function(name, array) { + var uniform = this.gl.getUniformLocation(this.program, name); + this.gl.uniformMatrix4fv(uniform, false, array); + } +}; +module.exports = Program; + + +},{"../utils/assert":20}],6:[function(require,module,exports){ +"use strict"; + +var assert = require('../utils/assert'); + +/** + * Represents a WebGL shader script. + */ + +function Script() {} + +Script.createFromElementId = function(id) { + var script = document.getElementById(id); + + // Didn't find an element with the specified ID, abort. + assert(script , "Could not find shader with ID: " + id); + + // Walk through the source element's children, building the shader source string. + var source = ""; + var currentChild = script .firstChild; + while(currentChild) { + if (currentChild.nodeType == 3) { + source += currentChild.textContent; + } + currentChild = currentChild.nextSibling; + } + + var res = new Scriptor(); + res.type = script.type; + res.source = source; + return res; +}; + +Script.createFromSource = function(type, source) { + var res = new Script(); + res.type = type; + res.source = source; + return res; +} + + +module.exports = Script; +},{"../utils/assert":20}],7:[function(require,module,exports){ +"use strict"; + +var error = require('../utils/error'); + +/** + * Represents a WebGL shader object and provides a mechanism to load shaders from HTML + * script tags. + */ + + +function Shader(gl, script) { + + // Now figure out what type of shader script we have, based on its MIME type. + if (script.type == "x-shader/x-fragment") { + this.shader = gl.createShader(gl.FRAGMENT_SHADER); + } else if (script.type == "x-shader/x-vertex") { + this.shader = gl.createShader(gl.VERTEX_SHADER); + } else { + error("Unknown shader type: " + script.type); + return; + } + + // Send the source to the shader object. + gl.shaderSource(this.shader, script.source); + + // Compile the shader program. + gl.compileShader(this.shader); + + // See if it compiled successfully. + if (!gl.getShaderParameter(this.shader, gl.COMPILE_STATUS)) { + error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(this.shader)); + return; + } +} +module.exports = Shader; + + + + +},{"../utils/error":21}],8:[function(require,module,exports){ +"use strict"; + +var assert = require('../utils/assert'); + +/** + * Represents a WebGL texture object. + */ + +function Texture(gl, size, format) { + this.gl = gl; + this.size = size; + this.texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + this.format = format ? format : gl.LUMINANCE; + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, size.w, size.h, 0, this.format, gl.UNSIGNED_BYTE, null); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); +} + +var textureIDs = null; +Texture.prototype = { + fill: function(textureData, useTexSubImage2D) { + var gl = this.gl; + assert(textureData.length >= this.size.w * this.size.h, + "Texture size mismatch, data:" + textureData.length + ", texture: " + this.size.w * this.size.h); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + if (useTexSubImage2D) { + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.size.w , this.size.h, this.format, gl.UNSIGNED_BYTE, textureData); + } else { + // texImage2D seems to be faster, thus keeping it as the default + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.size.w, this.size.h, 0, this.format, gl.UNSIGNED_BYTE, textureData); + } + }, + bind: function(n, program, name) { + var gl = this.gl; + if (!textureIDs) { + textureIDs = [gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2]; + } + gl.activeTexture(textureIDs[n]); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.uniform1i(gl.getUniformLocation(program.program, name), n); + } +}; +module.exports = Texture; + + +},{"../utils/assert":20}],9:[function(require,module,exports){ +"use strict"; + +/** + * Generic WebGL backed canvas that sets up: a quad to paint a texture on, appropriate vertex/fragment shaders, + * scene parameters and other things. Specialized versions of this class can be created by overriding several + * initialization methods. + + */ + +var Script = require('./Script'); +var error = require('../utils/error'); +var makePerspective = require('../utils/glUtils').makePerspective; +var Matrix = require('sylvester.js').Matrix; +var Class = require('uclass'); + + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", ` + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D texture; + void main(void) { + gl_FragColor = texture2D(texture, vTextureCoord); + } +`); + +var WebGLCanvas = new Class({ + + initialize : function(canvas, size, useFrameBuffer) { + + this.canvas = canvas; + this.size = size; + this.canvas.width = size.w; + this.canvas.height = size.h; + + this.onInitWebGL(); + this.onInitShaders(); + this.initBuffers(); + + if (useFrameBuffer) + this.initFramebuffer(); + + this.onInitTextures(); + this.initScene(); + }, + + +/** + * Initialize a frame buffer so that we can render off-screen. + */ + initFramebuffer : function() { + + var gl = this.gl; + + // Create framebuffer object and texture. + this.framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + this.framebufferTexture = new Texture(this.gl, this.size, gl.RGBA); + + // Create and allocate renderbuffer for depth data. + var renderbuffer = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.size.w, this.size.h); + + // Attach texture and renderbuffer to the framebuffer. + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.framebufferTexture.texture, 0); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer); + }, + + + +/** + * Initialize vertex and texture coordinate buffers for a plane. + */ + initBuffers : function () { + var tmp; + var gl = this.gl; + + // Create vertex position buffer. + this.quadVPBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer); + tmp = [ + 1.0, 1.0, 0.0, + -1.0, 1.0, 0.0, + 1.0, -1.0, 0.0, + -1.0, -1.0, 0.0]; + + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW); + this.quadVPBuffer.itemSize = 3; + this.quadVPBuffer.numItems = 4; + + /* + +--------------------+ + | -1,1 (1) | 1,1 (0) + | | + | | + | | + | | + | | + | -1,-1 (3) | 1,-1 (2) + +--------------------+ + */ + + var scaleX = 1.0; + var scaleY = 1.0; + + // Create vertex texture coordinate buffer. + this.quadVTCBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer); + tmp = [ + scaleX, 0.0, + 0.0, 0.0, + scaleX, scaleY, + 0.0, scaleY, + ]; + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW); + }, + + + mvIdentity : function () { + this.mvMatrix = Matrix.I(4); + }, + + mvMultiply : function(m) { + this.mvMatrix = this.mvMatrix.x(m); + }, + + mvTranslate : function (m) { + this.mvMultiply(Matrix.Translation($V([m[0], m[1], m[2]])).ensure4x4()); + }, + + setMatrixUniforms : function () { + this.program.setMatrixUniform("uPMatrix", new Float32Array(this.perspectiveMatrix.flatten())); + this.program.setMatrixUniform("uMVMatrix", new Float32Array(this.mvMatrix.flatten())); + }, + + initScene : function() { + var gl = this.gl; + + // Establish the perspective with which we want to view the + // scene. Our field of view is 45 degrees, with a width/height + // ratio of 640:480, and we only want to see objects between 0.1 units + // and 100 units away from the camera. + + this.perspectiveMatrix = makePerspective(45, 1, 0.1, 100.0); + + // Set the drawing position to the "identity" point, which is + // the center of the scene. + this.mvIdentity(); + + // Now move the drawing position a bit to where we want to start + // drawing the square. + this.mvTranslate([0.0, 0.0, -2.4]); + + // Draw the cube by binding the array buffer to the cube's vertices + // array, setting attributes, and pushing it to GL. + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer); + gl.vertexAttribPointer(this.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); + + // Set the texture coordinates attribute for the vertices. + + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer); + gl.vertexAttribPointer(this.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + + this.onInitSceneTextures(); + + this.setMatrixUniforms(); + + if (this.framebuffer) { + console.log("Bound Frame Buffer"); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + } + }, + + + + toString: function() { + return "WebGLCanvas Size: " + this.size; + }, + + checkLastError: function (operation) { + var err = this.gl.getError(); + if (err != this.gl.NO_ERROR) { + var name = this.glNames[err]; + name = (name !== undefined) ? name + "(" + err + ")": + ("Unknown WebGL ENUM (0x" + value.toString(16) + ")"); + if (operation) { + console.log("WebGL Error: %s, %s", operation, name); + } else { + console.log("WebGL Error: %s", name); + } + console.trace(); + } + }, + + onInitWebGL: function () { + try { + this.gl = this.canvas.getContext("experimental-webgl"); + } catch(e) {} + + if (!this.gl) { + error("Unable to initialize WebGL. Your browser may not support it."); + } + if (this.glNames) { + return; + } + this.glNames = {}; + for (var propertyName in this.gl) { + if (typeof this.gl[propertyName] == 'number') { + this.glNames[this.gl[propertyName]] = propertyName; + } + } + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");; + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + var gl = this.gl; + this.texture = new Texture(gl, this.size, gl.RGBA); + }, + + onInitSceneTextures: function () { + this.texture.bind(0, this.program, "texture"); + }, + + drawScene: function() { + this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); + }, + + readPixels: function(buffer) { + var gl = this.gl; + gl.readPixels(0, 0, this.size.w, this.size.h, gl.RGBA, gl.UNSIGNED_BYTE, buffer); + }, + + +}); + + + +module.exports = WebGLCanvas; + +},{"../utils/error":21,"../utils/glUtils":22,"./Script":6,"sylvester.js":12,"uclass":47}],10:[function(require,module,exports){ +"use strict"; +var Class = require('uclass'); + +var YUVCanvas = new Class({ + + Binds : ['decode'], + + initialize : function(canvas, size) { + this.canvas = canvas; + this.canvasCtx = this.canvas.getContext("2d"); + this.canvasBuffer = this.canvasCtx.createImageData(size.w, size.h); + }, + + decode : function (buffer, width, height) { + if (!buffer) + return; + + var lumaSize = width * height; + var chromaSize = lumaSize >> 2; + + var ybuf = buffer.subarray(0, lumaSize); + var ubuf = buffer.subarray(lumaSize, lumaSize + chromaSize); + var vbuf = buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize); + + for (var y = 0; y < height; y++) { + for (var x = 0; x < width; x++) { + var yIndex = x + y * width; + var uIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2); + var vIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2); + var R = 1.164 * (ybuf[yIndex] - 16) + 1.596 * (vbuf[vIndex] - 128); + var G = 1.164 * (ybuf[yIndex] - 16) - 0.813 * (vbuf[vIndex] - 128) - 0.391 * (ubuf[uIndex] - 128); + var B = 1.164 * (ybuf[yIndex] - 16) + 2.018 * (ubuf[uIndex] - 128); + + var rgbIndex = yIndex * 4; + this.canvasBuffer.data[rgbIndex+0] = R; + this.canvasBuffer.data[rgbIndex+1] = G; + this.canvasBuffer.data[rgbIndex+2] = B; + this.canvasBuffer.data[rgbIndex+3] = 0xff; + } + } + + this.canvasCtx.putImageData(this.canvasBuffer, 0, 0); + + var date = new Date(); + //console.log("WSAvcPlayer: Decode time: " + (date.getTime() - this.rcvtime) + " ms"); + }, + +}); + + +module.exports = YUVCanvas; +},{"uclass":47}],11:[function(require,module,exports){ +"use strict"; + +var Program = require('./Program'); +var Shader = require('./Shader'); +var Texture = require('./Texture'); +var Script = require('./Script'); +var WebGLCanvas = require('./WebGLCanvas'); + +var Class = require('uclass'); + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", ` + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D YTexture; + uniform sampler2D UTexture; + uniform sampler2D VTexture; + const mat4 YUV2RGB = mat4 + ( + 1.1643828125, 0, 1.59602734375, -.87078515625, + 1.1643828125, -.39176171875, -.81296875, .52959375, + 1.1643828125, 2.017234375, 0, -1.081390625, + 0, 0, 0, 1 + ); + + void main(void) { + gl_FragColor = vec4( texture2D(YTexture, vTextureCoord).x, texture2D(UTexture, vTextureCoord).x, texture2D(VTexture, vTextureCoord).x, 1) * YUV2RGB; + } +`); + + + + +var YUVWebGLCanvas = new Class({ + Extends : WebGLCanvas, + Binds : ['decode'], + + initialize : function(canvas, size) { + YUVWebGLCanvas.parent.initialize.call(this, canvas, size); + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");; + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + console.log("creatingTextures: size: " + this.size); + this.YTexture = new Texture(this.gl, this.size); + this.UTexture = new Texture(this.gl, this.size.getHalfSize()); + this.VTexture = new Texture(this.gl, this.size.getHalfSize()); + }, + + onInitSceneTextures: function () { + this.YTexture.bind(0, this.program, "YTexture"); + this.UTexture.bind(1, this.program, "UTexture"); + this.VTexture.bind(2, this.program, "VTexture"); + }, + + fillYUVTextures: function(y, u, v) { + this.YTexture.fill(y); + this.UTexture.fill(u); + this.VTexture.fill(v); + }, + + decode: function(buffer, width, height) { + + if (!buffer) + return; + + var lumaSize = width * height; + var chromaSize = lumaSize >> 2; + + this.YTexture.fill(buffer.subarray(0, lumaSize)); + this.UTexture.fill(buffer.subarray(lumaSize, lumaSize + chromaSize)); + this.VTexture.fill(buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize)); + this.drawScene(); + }, + + toString: function() { + return "YUVCanvas Size: " + this.size; + } +}); + + + + + +module.exports = YUVWebGLCanvas; + +},{"./Program":5,"./Script":6,"./Shader":7,"./Texture":8,"./WebGLCanvas":9,"uclass":47}],12:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel + +var global = (Function('return this'))(); + +exports.Vector = require('./vector'); +global.$V = exports.Vector.create; +exports.Matrix = require('./matrix'); +global.$M = exports.Matrix.create; +exports.Line = require('./line'); +global.$L = exports.Line.create; +exports.Plane = require('./plane'); +global.$P = exports.Plane.create; +exports.Line.Segment = require('./line.segment'); +exports.Sylvester = require('./sylvester'); + +},{"./line":13,"./line.segment":14,"./matrix":15,"./plane":16,"./sylvester":17,"./vector":18}],13:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +var Vector = require('./vector'); +var Matrix = require('./matrix'); +var Plane = require('./plane'); +var Sylvester = require('./sylvester'); + +// Line class - depends on Vector, and some methods require Matrix and Plane. + +function Line() {} +Line.prototype = { + + // Returns true if the argument occupies the same space as the line + eql: function(line) { + return (this.isParallelTo(line) && this.contains(line.anchor)); + }, + + // Returns a copy of the line + dup: function() { + return Line.create(this.anchor, this.direction); + }, + + // Returns the result of translating the line by the given vector/array + translate: function(vector) { + var V = vector.elements || vector; + return Line.create([ + this.anchor.elements[0] + V[0], + this.anchor.elements[1] + V[1], + this.anchor.elements[2] + (V[2] || 0) + ], this.direction); + }, + + // Returns true if the line is parallel to the argument. Here, 'parallel to' + // means that the argument's direction is either parallel or antiparallel to + // the line's own direction. A line is parallel to a plane if the two do not + // have a unique intersection. + isParallelTo: function(obj) { + if (obj.normal || (obj.start && obj.end)) { return obj.isParallelTo(this); } + var theta = this.direction.angleFrom(obj.direction); + return (Math.abs(theta) <= Sylvester.precision || Math.abs(theta - Math.PI) <= Sylvester.precision); + }, + + // Returns the line's perpendicular distance from the argument, + // which can be a point, a line or a plane + distanceFrom: function(obj) { + if (obj.normal || (obj.start && obj.end)) { return obj.distanceFrom(this); } + if (obj.direction) { + // obj is a line + if (this.isParallelTo(obj)) { return this.distanceFrom(obj.anchor); } + var N = this.direction.cross(obj.direction).toUnitVector().elements; + var A = this.anchor.elements, B = obj.anchor.elements; + return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]); + } else { + // obj is a point + var P = obj.elements || obj; + var A = this.anchor.elements, D = this.direction.elements; + var PA1 = P[0] - A[0], PA2 = P[1] - A[1], PA3 = (P[2] || 0) - A[2]; + var modPA = Math.sqrt(PA1*PA1 + PA2*PA2 + PA3*PA3); + if (modPA === 0) return 0; + // Assumes direction vector is normalized + var cosTheta = (PA1 * D[0] + PA2 * D[1] + PA3 * D[2]) / modPA; + var sin2 = 1 - cosTheta*cosTheta; + return Math.abs(modPA * Math.sqrt(sin2 < 0 ? 0 : sin2)); + } + }, + + // Returns true iff the argument is a point on the line, or if the argument + // is a line segment lying within the receiver + contains: function(obj) { + if (obj.start && obj.end) { return this.contains(obj.start) && this.contains(obj.end); } + var dist = this.distanceFrom(obj); + return (dist !== null && dist <= Sylvester.precision); + }, + + // Returns the distance from the anchor of the given point. Negative values are + // returned for points that are in the opposite direction to the line's direction from + // the line's anchor point. + positionOf: function(point) { + if (!this.contains(point)) { return null; } + var P = point.elements || point; + var A = this.anchor.elements, D = this.direction.elements; + return (P[0] - A[0]) * D[0] + (P[1] - A[1]) * D[1] + ((P[2] || 0) - A[2]) * D[2]; + }, + + // Returns true iff the line lies in the given plane + liesIn: function(plane) { + return plane.contains(this); + }, + + // Returns true iff the line has a unique point of intersection with the argument + intersects: function(obj) { + if (obj.normal) { return obj.intersects(this); } + return (!this.isParallelTo(obj) && this.distanceFrom(obj) <= Sylvester.precision); + }, + + // Returns the unique intersection point with the argument, if one exists + intersectionWith: function(obj) { + if (obj.normal || (obj.start && obj.end)) { return obj.intersectionWith(this); } + if (!this.intersects(obj)) { return null; } + var P = this.anchor.elements, X = this.direction.elements, + Q = obj.anchor.elements, Y = obj.direction.elements; + var X1 = X[0], X2 = X[1], X3 = X[2], Y1 = Y[0], Y2 = Y[1], Y3 = Y[2]; + var PsubQ1 = P[0] - Q[0], PsubQ2 = P[1] - Q[1], PsubQ3 = P[2] - Q[2]; + var XdotQsubP = - X1*PsubQ1 - X2*PsubQ2 - X3*PsubQ3; + var YdotPsubQ = Y1*PsubQ1 + Y2*PsubQ2 + Y3*PsubQ3; + var XdotX = X1*X1 + X2*X2 + X3*X3; + var YdotY = Y1*Y1 + Y2*Y2 + Y3*Y3; + var XdotY = X1*Y1 + X2*Y2 + X3*Y3; + var k = (XdotQsubP * YdotY / XdotX + XdotY * YdotPsubQ) / (YdotY - XdotY * XdotY); + return Vector.create([P[0] + k*X1, P[1] + k*X2, P[2] + k*X3]); + }, + + // Returns the point on the line that is closest to the given point or line/line segment + pointClosestTo: function(obj) { + if (obj.start && obj.end) { + // obj is a line segment + var P = obj.pointClosestTo(this); + return (P === null) ? null : this.pointClosestTo(P); + } else if (obj.direction) { + // obj is a line + if (this.intersects(obj)) { return this.intersectionWith(obj); } + if (this.isParallelTo(obj)) { return null; } + var D = this.direction.elements, E = obj.direction.elements; + var D1 = D[0], D2 = D[1], D3 = D[2], E1 = E[0], E2 = E[1], E3 = E[2]; + // Create plane containing obj and the shared normal and intersect this with it + // Thank you: http://www.cgafaq.info/wiki/Line-line_distance + var x = (D3 * E1 - D1 * E3), y = (D1 * E2 - D2 * E1), z = (D2 * E3 - D3 * E2); + var N = [x * E3 - y * E2, y * E1 - z * E3, z * E2 - x * E1]; + var P = Plane.create(obj.anchor, N); + return P.intersectionWith(this); + } else { + // obj is a point + var P = obj.elements || obj; + if (this.contains(P)) { return Vector.create(P); } + var A = this.anchor.elements, D = this.direction.elements; + var D1 = D[0], D2 = D[1], D3 = D[2], A1 = A[0], A2 = A[1], A3 = A[2]; + var x = D1 * (P[1]-A2) - D2 * (P[0]-A1), y = D2 * ((P[2] || 0) - A3) - D3 * (P[1]-A2), + z = D3 * (P[0]-A1) - D1 * ((P[2] || 0) - A3); + var V = Vector.create([D2 * x - D3 * z, D3 * y - D1 * x, D1 * z - D2 * y]); + var k = this.distanceFrom(P) / V.modulus(); + return Vector.create([ + P[0] + V.elements[0] * k, + P[1] + V.elements[1] * k, + (P[2] || 0) + V.elements[2] * k + ]); + } + }, + + // Returns a copy of the line rotated by t radians about the given line. Works by + // finding the argument's closest point to this line's anchor point (call this C) and + // rotating the anchor about C. Also rotates the line's direction about the argument's. + // Be careful with this - the rotation axis' direction affects the outcome! + rotate: function(t, line) { + // If we're working in 2D + if (typeof(line.direction) == 'undefined') { line = Line.create(line.to3D(), Vector.k); } + var R = Matrix.Rotation(t, line.direction).elements; + var C = line.pointClosestTo(this.anchor).elements; + var A = this.anchor.elements, D = this.direction.elements; + var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2]; + var x = A1 - C1, y = A2 - C2, z = A3 - C3; + return Line.create([ + C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z, + C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z, + C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z + ], [ + R[0][0] * D[0] + R[0][1] * D[1] + R[0][2] * D[2], + R[1][0] * D[0] + R[1][1] * D[1] + R[1][2] * D[2], + R[2][0] * D[0] + R[2][1] * D[1] + R[2][2] * D[2] + ]); + }, + + // Returns a copy of the line with its direction vector reversed. + // Useful when using lines for rotations. + reverse: function() { + return Line.create(this.anchor, this.direction.x(-1)); + }, + + // Returns the line's reflection in the given point or line + reflectionIn: function(obj) { + if (obj.normal) { + // obj is a plane + var A = this.anchor.elements, D = this.direction.elements; + var A1 = A[0], A2 = A[1], A3 = A[2], D1 = D[0], D2 = D[1], D3 = D[2]; + var newA = this.anchor.reflectionIn(obj).elements; + // Add the line's direction vector to its anchor, then mirror that in the plane + var AD1 = A1 + D1, AD2 = A2 + D2, AD3 = A3 + D3; + var Q = obj.pointClosestTo([AD1, AD2, AD3]).elements; + var newD = [Q[0] + (Q[0] - AD1) - newA[0], Q[1] + (Q[1] - AD2) - newA[1], Q[2] + (Q[2] - AD3) - newA[2]]; + return Line.create(newA, newD); + } else if (obj.direction) { + // obj is a line - reflection obtained by rotating PI radians about obj + return this.rotate(Math.PI, obj); + } else { + // obj is a point - just reflect the line's anchor in it + var P = obj.elements || obj; + return Line.create(this.anchor.reflectionIn([P[0], P[1], (P[2] || 0)]), this.direction); + } + }, + + // Set the line's anchor point and direction. + setVectors: function(anchor, direction) { + // Need to do this so that line's properties are not + // references to the arguments passed in + anchor = Vector.create(anchor); + direction = Vector.create(direction); + if (anchor.elements.length == 2) {anchor.elements.push(0); } + if (direction.elements.length == 2) { direction.elements.push(0); } + if (anchor.elements.length > 3 || direction.elements.length > 3) { return null; } + var mod = direction.modulus(); + if (mod === 0) { return null; } + this.anchor = anchor; + this.direction = Vector.create([ + direction.elements[0] / mod, + direction.elements[1] / mod, + direction.elements[2] / mod + ]); + return this; + } +}; + +// Constructor function +Line.create = function(anchor, direction) { + var L = new Line(); + return L.setVectors(anchor, direction); +}; + +// Axes +Line.X = Line.create(Vector.Zero(3), Vector.i); +Line.Y = Line.create(Vector.Zero(3), Vector.j); +Line.Z = Line.create(Vector.Zero(3), Vector.k); + +module.exports = Line; + +},{"./matrix":15,"./plane":16,"./sylvester":17,"./vector":18}],14:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// Line.Segment class - depends on Line and its dependencies. + +var Line = require('./line'); +var Vector = require('./vector'); + +Line.Segment = function() {}; +Line.Segment.prototype = { + + // Returns true iff the line segment is equal to the argument + eql: function(segment) { + return (this.start.eql(segment.start) && this.end.eql(segment.end)) || + (this.start.eql(segment.end) && this.end.eql(segment.start)); + }, + + // Returns a copy of the line segment + dup: function() { + return Line.Segment.create(this.start, this.end); + }, + + // Returns the length of the line segment + length: function() { + var A = this.start.elements, B = this.end.elements; + var C1 = B[0] - A[0], C2 = B[1] - A[1], C3 = B[2] - A[2]; + return Math.sqrt(C1*C1 + C2*C2 + C3*C3); + }, + + // Returns the line segment as a vector equal to its + // end point relative to its endpoint + toVector: function() { + var A = this.start.elements, B = this.end.elements; + return Vector.create([B[0] - A[0], B[1] - A[1], B[2] - A[2]]); + }, + + // Returns the segment's midpoint as a vector + midpoint: function() { + var A = this.start.elements, B = this.end.elements; + return Vector.create([(B[0] + A[0])/2, (B[1] + A[1])/2, (B[2] + A[2])/2]); + }, + + // Returns the plane that bisects the segment + bisectingPlane: function() { + return Plane.create(this.midpoint(), this.toVector()); + }, + + // Returns the result of translating the line by the given vector/array + translate: function(vector) { + var V = vector.elements || vector; + var S = this.start.elements, E = this.end.elements; + return Line.Segment.create( + [S[0] + V[0], S[1] + V[1], S[2] + (V[2] || 0)], + [E[0] + V[0], E[1] + V[1], E[2] + (V[2] || 0)] + ); + }, + + // Returns true iff the line segment is parallel to the argument. It simply forwards + // the method call onto its line property. + isParallelTo: function(obj) { + return this.line.isParallelTo(obj); + }, + + // Returns the distance between the argument and the line segment's closest point to the argument + distanceFrom: function(obj) { + var P = this.pointClosestTo(obj); + return (P === null) ? null : P.distanceFrom(obj); + }, + + // Returns true iff the given point lies on the segment + contains: function(obj) { + if (obj.start && obj.end) { return this.contains(obj.start) && this.contains(obj.end); } + var P = (obj.elements || obj).slice(); + if (P.length == 2) { P.push(0); } + if (this.start.eql(P)) { return true; } + var S = this.start.elements; + var V = Vector.create([S[0] - P[0], S[1] - P[1], S[2] - (P[2] || 0)]); + var vect = this.toVector(); + return V.isAntiparallelTo(vect) && V.modulus() <= vect.modulus(); + }, + + // Returns true iff the line segment intersects the argument + intersects: function(obj) { + return (this.intersectionWith(obj) !== null); + }, + + // Returns the unique point of intersection with the argument + intersectionWith: function(obj) { + if (!this.line.intersects(obj)) { return null; } + var P = this.line.intersectionWith(obj); + return (this.contains(P) ? P : null); + }, + + // Returns the point on the line segment closest to the given object + pointClosestTo: function(obj) { + if (obj.normal) { + // obj is a plane + var V = this.line.intersectionWith(obj); + if (V === null) { return null; } + return this.pointClosestTo(V); + } else { + // obj is a line (segment) or point + var P = this.line.pointClosestTo(obj); + if (P === null) { return null; } + if (this.contains(P)) { return P; } + return (this.line.positionOf(P) < 0 ? this.start : this.end).dup(); + } + }, + + // Set the start and end-points of the segment + setPoints: function(startPoint, endPoint) { + startPoint = Vector.create(startPoint).to3D(); + endPoint = Vector.create(endPoint).to3D(); + if (startPoint === null || endPoint === null) { return null; } + this.line = Line.create(startPoint, endPoint.subtract(startPoint)); + this.start = startPoint; + this.end = endPoint; + return this; + } +}; + +// Constructor function +Line.Segment.create = function(v1, v2) { + var S = new Line.Segment(); + return S.setPoints(v1, v2); +}; + +module.exports = Line.Segment; + +},{"./line":13,"./vector":18}],15:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// Matrix class - depends on Vector. + +var Sylvester = require('./sylvester'); +var Vector = require('./vector'); + +// augment a matrix M with identity rows/cols +function identSize(M, m, n, k) { + var e = M.elements; + var i = k - 1; + + while(i--) { + var row = []; + + for(var j = 0; j < n; j++) + row.push(j == i ? 1 : 0); + + e.unshift(row); + } + + for(var i = k - 1; i < m; i++) { + while(e[i].length < n) + e[i].unshift(0); + } + + return $M(e); +} + +function pca(X) { + var Sigma = X.transpose().x(X).x(1 / X.rows()); + var svd = Sigma.svd(); + return {U: svd.U, S: svd.S}; +} + +// singular value decomposition in pure javascript +function svdJs() { + var A = this; + var V = Matrix.I(A.rows()); + var S = A.transpose(); + var U = Matrix.I(A.cols()); + var err = Number.MAX_VALUE; + var i = 0; + var maxLoop = 100; + + while(err > 2.2737e-13 && i < maxLoop) { + var qr = S.transpose().qrJs(); + S = qr.R; + V = V.x(qr.Q); + qr = S.transpose().qrJs(); + U = U.x(qr.Q); + S = qr.R; + + var e = S.triu(1).unroll().norm(); + var f = S.diagonal().norm(); + + if(f == 0) + f = 1; + + err = e / f; + + i++; + } + + var ss = S.diagonal(); + var s = []; + + for(var i = 1; i <= ss.cols(); i++) { + var ssn = ss.e(i); + s.push(Math.abs(ssn)); + + if(ssn < 0) { + for(var j = 0; j < U.rows(); j++) { + V.elements[j][i - 1] = -(V.elements[j][i - 1]); + } + } + } + + return {U: U, S: $V(s).toDiagonalMatrix(), V: V}; +} + + + +// QR decomposition in pure javascript +function qrJs() { + var m = this.rows(); + var n = this.cols(); + var Q = Matrix.I(m); + var A = this; + + for(var k = 1; k < Math.min(m, n); k++) { + var ak = A.slice(k, 0, k, k).col(1); + var oneZero = [1]; + + while(oneZero.length <= m - k) + oneZero.push(0); + + oneZero = $V(oneZero); + var vk = ak.add(oneZero.x(ak.norm() * Math.sign(ak.e(1)))); + var Vk = $M(vk); + var Hk = Matrix.I(m - k + 1).subtract(Vk.x(2).x(Vk.transpose()).div(Vk.transpose().x(Vk).e(1, 1))); + var Qk = identSize(Hk, m, n, k); + A = Qk.x(A); + // slow way to compute Q + Q = Q.x(Qk); + } + + return {Q: Q, R: A}; +} + + + + +function Matrix() {} +Matrix.prototype = { + // solve a system of linear equations (work in progress) + solve: function(b) { + var lu = this.lu(); + b = lu.P.x(b); + var y = lu.L.forwardSubstitute(b); + var x = lu.U.backSubstitute(y); + return lu.P.x(x); + //return this.inv().x(b); + }, + + // project a matrix onto a lower dim + pcaProject: function(k, U) { + var U = U || pca(this).U; + var Ureduce= U.slice(1, U.rows(), 1, k); + return {Z: this.x(Ureduce), U: U}; + }, + + // recover a matrix to a higher dimension + pcaRecover: function(U) { + var k = this.cols(); + var Ureduce = U.slice(1, U.rows(), 1, k); + return this.x(Ureduce.transpose()); + }, + + // grab the upper triangular part of the matrix + triu: function(k) { + if(!k) + k = 0; + + return this.map(function(x, i, j) { + return j - i >= k ? x : 0; + }); + }, + + // unroll a matrix into a vector + unroll: function() { + var v = []; + + for(var i = 1; i <= this.cols(); i++) { + for(var j = 1; j <= this.rows(); j++) { + v.push(this.e(j, i)); + } + } + + return $V(v); + }, + + // return a sub-block of the matrix + slice: function(startRow, endRow, startCol, endCol) { + var x = []; + + if(endRow == 0) + endRow = this.rows(); + + if(endCol == 0) + endCol = this.cols(); + + for(i = startRow; i <= endRow; i++) { + var row = []; + + for(j = startCol; j <= endCol; j++) { + row.push(this.e(i, j)); + } + + x.push(row); + } + + return $M(x); + }, + + // Returns element (i,j) of the matrix + e: function(i,j) { + if (i < 1 || i > this.elements.length || j < 1 || j > this.elements[0].length) { return null; } + return this.elements[i - 1][j - 1]; + }, + + // Returns row k of the matrix as a vector + row: function(i) { + if (i > this.elements.length) { return null; } + return $V(this.elements[i - 1]); + }, + + // Returns column k of the matrix as a vector + col: function(j) { + if (j > this.elements[0].length) { return null; } + var col = [], n = this.elements.length; + for (var i = 0; i < n; i++) { col.push(this.elements[i][j - 1]); } + return $V(col); + }, + + // Returns the number of rows/columns the matrix has + dimensions: function() { + return {rows: this.elements.length, cols: this.elements[0].length}; + }, + + // Returns the number of rows in the matrix + rows: function() { + return this.elements.length; + }, + + // Returns the number of columns in the matrix + cols: function() { + return this.elements[0].length; + }, + + approxEql: function(matrix) { + return this.eql(matrix, Sylvester.approxPrecision); + }, + + // Returns true iff the matrix is equal to the argument. You can supply + // a vector as the argument, in which case the receiver must be a + // one-column matrix equal to the vector. + eql: function(matrix, precision) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + if (this.elements.length != M.length || + this.elements[0].length != M[0].length) { return false; } + var i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { j = nj; + while (j--) { + if (Math.abs(this.elements[i][j] - M[i][j]) > (precision || Sylvester.precision)) { return false; } + } + } + return true; + }, + + // Returns a copy of the matrix + dup: function() { + return Matrix.create(this.elements); + }, + + // Maps the matrix to another matrix (of the same dimensions) according to the given function + map: function(fn) { + var els = [], i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { j = nj; + els[i] = []; + while (j--) { + els[i][j] = fn(this.elements[i][j], i + 1, j + 1); + } + } + return Matrix.create(els); + }, + + // Returns true iff the argument has the same dimensions as the matrix + isSameSizeAs: function(matrix) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + return (this.elements.length == M.length && + this.elements[0].length == M[0].length); + }, + + // Returns the result of adding the argument to the matrix + add: function(matrix) { + if(typeof(matrix) == 'number') { + return this.map(function(x, i, j) { return x + matrix}); + } else { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + if (!this.isSameSizeAs(M)) { return null; } + return this.map(function(x, i, j) { return x + M[i - 1][j - 1]; }); + } + }, + + // Returns the result of subtracting the argument from the matrix + subtract: function(matrix) { + if(typeof(matrix) == 'number') { + return this.map(function(x, i, j) { return x - matrix}); + } else { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + if (!this.isSameSizeAs(M)) { return null; } + return this.map(function(x, i, j) { return x - M[i - 1][j - 1]; }); + } + }, + + // Returns true iff the matrix can multiply the argument from the left + canMultiplyFromLeft: function(matrix) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + // this.columns should equal matrix.rows + return (this.elements[0].length == M.length); + }, + + // Returns the result of a multiplication-style operation the matrix from the right by the argument. + // If the argument is a scalar then just operate on all the elements. If the argument is + // a vector, a vector is returned, which saves you having to remember calling + // col(1) on the result. + mulOp: function(matrix, op) { + if (!matrix.elements) { + return this.map(function(x) { return op(x, matrix); }); + } + + var returnVector = matrix.modulus ? true : false; + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') + M = Matrix.create(M).elements; + if (!this.canMultiplyFromLeft(M)) + return null; + var e = this.elements, rowThis, rowElem, elements = [], + sum, m = e.length, n = M[0].length, o = e[0].length, i = m, j, k; + + while (i--) { + rowElem = []; + rowThis = e[i]; + j = n; + + while (j--) { + sum = 0; + k = o; + + while (k--) { + sum += op(rowThis[k], M[k][j]); + } + + rowElem[j] = sum; + } + + elements[i] = rowElem; + } + + var M = Matrix.create(elements); + return returnVector ? M.col(1) : M; + }, + + // Returns the result of dividing the matrix from the right by the argument. + // If the argument is a scalar then just divide all the elements. If the argument is + // a vector, a vector is returned, which saves you having to remember calling + // col(1) on the result. + div: function(matrix) { + return this.mulOp(matrix, function(x, y) { return x / y}); + }, + + // Returns the result of multiplying the matrix from the right by the argument. + // If the argument is a scalar then just multiply all the elements. If the argument is + // a vector, a vector is returned, which saves you having to remember calling + // col(1) on the result. + multiply: function(matrix) { + return this.mulOp(matrix, function(x, y) { return x * y}); + }, + + x: function(matrix) { return this.multiply(matrix); }, + + elementMultiply: function(v) { + return this.map(function(k, i, j) { + return v.e(i, j) * k; + }); + }, + + // sum all elements in the matrix + sum: function() { + var sum = 0; + + this.map(function(x) { sum += x;}); + + return sum; + }, + + // Returns a Vector of each colum averaged. + mean: function() { + var dim = this.dimensions(); + var r = []; + for (var i = 1; i <= dim.cols; i++) { + r.push(this.col(i).sum() / dim.rows); + } + return $V(r); + }, + + column: function(n) { + return this.col(n); + }, + + // element-wise log + log: function() { + return this.map(function(x) { return Math.log(x); }); + }, + + // Returns a submatrix taken from the matrix + // Argument order is: start row, start col, nrows, ncols + // Element selection wraps if the required index is outside the matrix's bounds, so you could + // use this to perform row/column cycling or copy-augmenting. + minor: function(a, b, c, d) { + var elements = [], ni = c, i, nj, j; + var rows = this.elements.length, cols = this.elements[0].length; + while (ni--) { + i = c - ni - 1; + elements[i] = []; + nj = d; + while (nj--) { + j = d - nj - 1; + elements[i][j] = this.elements[(a + i - 1) % rows][(b + j - 1) % cols]; + } + } + return Matrix.create(elements); + }, + + // Returns the transpose of the matrix + transpose: function() { + var rows = this.elements.length, i, cols = this.elements[0].length, j; + var elements = [], i = cols; + while (i--) { + j = rows; + elements[i] = []; + while (j--) { + elements[i][j] = this.elements[j][i]; + } + } + return Matrix.create(elements); + }, + + // Returns true iff the matrix is square + isSquare: function() { + return (this.elements.length == this.elements[0].length); + }, + + // Returns the (absolute) largest element of the matrix + max: function() { + var m = 0, i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { + j = nj; + while (j--) { + if (Math.abs(this.elements[i][j]) > Math.abs(m)) { m = this.elements[i][j]; } + } + } + return m; + }, + + // Returns the indeces of the first match found by reading row-by-row from left to right + indexOf: function(x) { + var index = null, ni = this.elements.length, i, nj = this.elements[0].length, j; + for (i = 0; i < ni; i++) { + for (j = 0; j < nj; j++) { + if (this.elements[i][j] == x) { return {i: i + 1, j: j + 1}; } + } + } + return null; + }, + + // If the matrix is square, returns the diagonal elements as a vector. + // Otherwise, returns null. + diagonal: function() { + if (!this.isSquare) { return null; } + var els = [], n = this.elements.length; + for (var i = 0; i < n; i++) { + els.push(this.elements[i][i]); + } + return $V(els); + }, + + // Make the matrix upper (right) triangular by Gaussian elimination. + // This method only adds multiples of rows to other rows. No rows are + // scaled up or switched, and the determinant is preserved. + toRightTriangular: function() { + var M = this.dup(), els; + var n = this.elements.length, i, j, np = this.elements[0].length, p; + for (i = 0; i < n; i++) { + if (M.elements[i][i] == 0) { + for (j = i + 1; j < n; j++) { + if (M.elements[j][i] != 0) { + els = []; + for (p = 0; p < np; p++) { els.push(M.elements[i][p] + M.elements[j][p]); } + M.elements[i] = els; + break; + } + } + } + if (M.elements[i][i] != 0) { + for (j = i + 1; j < n; j++) { + var multiplier = M.elements[j][i] / M.elements[i][i]; + els = []; + for (p = 0; p < np; p++) { + // Elements with column numbers up to an including the number + // of the row that we're subtracting can safely be set straight to + // zero, since that's the point of this routine and it avoids having + // to loop over and correct rounding errors later + els.push(p <= i ? 0 : M.elements[j][p] - M.elements[i][p] * multiplier); + } + M.elements[j] = els; + } + } + } + return M; + }, + + toUpperTriangular: function() { return this.toRightTriangular(); }, + + // Returns the determinant for square matrices + determinant: function() { + if (!this.isSquare()) { return null; } + if (this.cols == 1 && this.rows == 1) { return this.row(1); } + if (this.cols == 0 && this.rows == 0) { return 1; } + var M = this.toRightTriangular(); + var det = M.elements[0][0], n = M.elements.length; + for (var i = 1; i < n; i++) { + det = det * M.elements[i][i]; + } + return det; + }, + det: function() { return this.determinant(); }, + + // Returns true iff the matrix is singular + isSingular: function() { + return (this.isSquare() && this.determinant() === 0); + }, + + // Returns the trace for square matrices + trace: function() { + if (!this.isSquare()) { return null; } + var tr = this.elements[0][0], n = this.elements.length; + for (var i = 1; i < n; i++) { + tr += this.elements[i][i]; + } + return tr; + }, + + tr: function() { return this.trace(); }, + + // Returns the rank of the matrix + rank: function() { + var M = this.toRightTriangular(), rank = 0; + var i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { + j = nj; + while (j--) { + if (Math.abs(M.elements[i][j]) > Sylvester.precision) { rank++; break; } + } + } + return rank; + }, + + rk: function() { return this.rank(); }, + + // Returns the result of attaching the given argument to the right-hand side of the matrix + augment: function(matrix) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + var T = this.dup(), cols = T.elements[0].length; + var i = T.elements.length, nj = M[0].length, j; + if (i != M.length) { return null; } + while (i--) { + j = nj; + while (j--) { + T.elements[i][cols + j] = M[i][j]; + } + } + return T; + }, + + // Returns the inverse (if one exists) using Gauss-Jordan + inverse: function() { + if (!this.isSquare() || this.isSingular()) { return null; } + var n = this.elements.length, i = n, j; + var M = this.augment(Matrix.I(n)).toRightTriangular(); + var np = M.elements[0].length, p, els, divisor; + var inverse_elements = [], new_element; + // Matrix is non-singular so there will be no zeros on the diagonal + // Cycle through rows from last to first + while (i--) { + // First, normalise diagonal elements to 1 + els = []; + inverse_elements[i] = []; + divisor = M.elements[i][i]; + for (p = 0; p < np; p++) { + new_element = M.elements[i][p] / divisor; + els.push(new_element); + // Shuffle off the current row of the right hand side into the results + // array as it will not be modified by later runs through this loop + if (p >= n) { inverse_elements[i].push(new_element); } + } + M.elements[i] = els; + // Then, subtract this row from those above it to + // give the identity matrix on the left hand side + j = i; + while (j--) { + els = []; + for (p = 0; p < np; p++) { + els.push(M.elements[j][p] - M.elements[i][p] * M.elements[j][i]); + } + M.elements[j] = els; + } + } + return Matrix.create(inverse_elements); + }, + + inv: function() { return this.inverse(); }, + + // Returns the result of rounding all the elements + round: function() { + return this.map(function(x) { return Math.round(x); }); + }, + + // Returns a copy of the matrix with elements set to the given value if they + // differ from it by less than Sylvester.precision + snapTo: function(x) { + return this.map(function(p) { + return (Math.abs(p - x) <= Sylvester.precision) ? x : p; + }); + }, + + // Returns a string representation of the matrix + inspect: function() { + var matrix_rows = []; + var n = this.elements.length; + for (var i = 0; i < n; i++) { + matrix_rows.push($V(this.elements[i]).inspect()); + } + return matrix_rows.join('\n'); + }, + + // Returns a array representation of the matrix + toArray: function() { + var matrix_rows = []; + var n = this.elements.length; + for (var i = 0; i < n; i++) { + matrix_rows.push(this.elements[i]); + } + return matrix_rows; + }, + + + // Set the matrix's elements from an array. If the argument passed + // is a vector, the resulting matrix will be a single column. + setElements: function(els) { + var i, j, elements = els.elements || els; + if (typeof(elements[0][0]) != 'undefined') { + i = elements.length; + this.elements = []; + while (i--) { + j = elements[i].length; + this.elements[i] = []; + while (j--) { + this.elements[i][j] = elements[i][j]; + } + } + return this; + } + var n = elements.length; + this.elements = []; + for (i = 0; i < n; i++) { + this.elements.push([elements[i]]); + } + return this; + }, + + // return the indexes of the columns with the largest value + // for each row + maxColumnIndexes: function() { + var maxes = []; + + for(var i = 1; i <= this.rows(); i++) { + var max = null; + var maxIndex = -1; + + for(var j = 1; j <= this.cols(); j++) { + if(max === null || this.e(i, j) > max) { + max = this.e(i, j); + maxIndex = j; + } + } + + maxes.push(maxIndex); + } + + return $V(maxes); + }, + + // return the largest values in each row + maxColumns: function() { + var maxes = []; + + for(var i = 1; i <= this.rows(); i++) { + var max = null; + + for(var j = 1; j <= this.cols(); j++) { + if(max === null || this.e(i, j) > max) { + max = this.e(i, j); + } + } + + maxes.push(max); + } + + return $V(maxes); + }, + + // return the indexes of the columns with the smallest values + // for each row + minColumnIndexes: function() { + var mins = []; + + for(var i = 1; i <= this.rows(); i++) { + var min = null; + var minIndex = -1; + + for(var j = 1; j <= this.cols(); j++) { + if(min === null || this.e(i, j) < min) { + min = this.e(i, j); + minIndex = j; + } + } + + mins.push(minIndex); + } + + return $V(mins); + }, + + // return the smallest values in each row + minColumns: function() { + var mins = []; + + for(var i = 1; i <= this.rows(); i++) { + var min = null; + + for(var j = 1; j <= this.cols(); j++) { + if(min === null || this.e(i, j) < min) { + min = this.e(i, j); + } + } + + mins.push(min); + } + + return $V(mins); + }, + + // perorm a partial pivot on the matrix. essentially move the largest + // row below-or-including the pivot and replace the pivot's row with it. + // a pivot matrix is returned so multiplication can perform the transform. + partialPivot: function(k, j, P, A, L) { + var maxIndex = 0; + var maxValue = 0; + + for(var i = k; i <= A.rows(); i++) { + if(Math.abs(A.e(i, j)) > maxValue) { + maxValue = Math.abs(A.e(k, j)); + maxIndex = i; + } + } + + if(maxIndex != k) { + var tmp = A.elements[k - 1]; + A.elements[k - 1] = A.elements[maxIndex - 1]; + A.elements[maxIndex - 1] = tmp; + + P.elements[k - 1][k - 1] = 0; + P.elements[k - 1][maxIndex - 1] = 1; + P.elements[maxIndex - 1][maxIndex - 1] = 0; + P.elements[maxIndex - 1][k - 1] = 1; + } + + return P; + }, + + // solve lower-triangular matrix * x = b via forward substitution + forwardSubstitute: function(b) { + var xa = []; + + for(var i = 1; i <= this.rows(); i++) { + var w = 0; + + for(var j = 1; j < i; j++) { + w += this.e(i, j) * xa[j - 1]; + } + + xa.push((b.e(i) - w) / this.e(i, i)); + } + + return $V(xa); + }, + + // solve an upper-triangular matrix * x = b via back substitution + backSubstitute: function(b) { + var xa = []; + + for(var i = this.rows(); i > 0; i--) { + var w = 0; + + for(var j = this.cols(); j > i; j--) { + w += this.e(i, j) * xa[this.rows() - j]; + } + + xa.push((b.e(i) - w) / this.e(i, i)); + } + + return $V(xa.reverse()); + }, + + luJs: luJs, + svdJs: svdJs, + qrJs: qrJs, +}; + + +var tolerance = 1.4901e-08; + +// pure Javascript LU factorization +function luJs() { + var A = this.dup(); + var L = Matrix.I(A.rows()); + var P = Matrix.I(A.rows()); + var U = Matrix.Zeros(A.rows(), A.cols()); + var p = 1; + + for(var k = 1; k <= Math.min(A.cols(), A.rows()); k++) { + P = A.partialPivot(k, p, P, A, L); + + for(var i = k + 1; i <= A.rows(); i++) { + var l = A.e(i, p) / A.e(k, p); + L.elements[i - 1][k - 1] = l; + + for(var j = k + 1 ; j <= A.cols(); j++) { + A.elements[i - 1][j - 1] -= A.e(k, j) * l; + } + } + + for(var j = k; j <= A.cols(); j++) { + U.elements[k - 1][j - 1] = A.e(k, j); + } + + if(p < A.cols()) + p++; + } + + return {L: L, U: U, P: P}; +} + + + +Matrix.prototype.svd = svdJs; +Matrix.prototype.qr = qrJs; +Matrix.prototype.lu = luJs; + +// Constructor function +Matrix.create = function(aElements) { + var M = new Matrix().setElements(aElements); + return M; +}; + +// Identity matrix of size n +Matrix.I = function(n) { + var els = [], i = n, j; + while (i--) { + j = n; + els[i] = []; + while (j--) { + els[i][j] = (i == j) ? 1 : 0; + } + } + return Matrix.create(els); +}; + +Matrix.loadFile = function(file) { + var fs = require('fs'); + var contents = fs.readFileSync(file, 'utf-8'); + var matrix = []; + + var rowArray = contents.split('\n'); + for (var i = 0; i < rowArray.length; i++) { + var d = rowArray[i].split(','); + if (d.length > 1) { + matrix.push(d); + } + } + + var M = new Matrix(); + return M.setElements(matrix); +}; + +// Diagonal matrix - all off-diagonal elements are zero +Matrix.Diagonal = function(elements) { + var i = elements.length; + var M = Matrix.I(i); + while (i--) { + M.elements[i][i] = elements[i]; + } + return M; +}; + +// Rotation matrix about some axis. If no axis is +// supplied, assume we're after a 2D transform +Matrix.Rotation = function(theta, a) { + if (!a) { + return Matrix.create([ + [Math.cos(theta), -Math.sin(theta)], + [Math.sin(theta), Math.cos(theta)] + ]); + } + var axis = a.dup(); + if (axis.elements.length != 3) { return null; } + var mod = axis.modulus(); + var x = axis.elements[0] / mod, y = axis.elements[1] / mod, z = axis.elements[2] / mod; + var s = Math.sin(theta), c = Math.cos(theta), t = 1 - c; + // Formula derived here: http://www.gamedev.net/reference/articles/article1199.asp + // That proof rotates the co-ordinate system so theta + // becomes -theta and sin becomes -sin here. + return Matrix.create([ + [t * x * x + c, t * x * y - s * z, t * x * z + s * y], + [t * x * y + s * z, t * y * y + c, t * y * z - s * x], + [t * x * z - s * y, t * y * z + s * x, t * z * z + c] + ]); +}; + +// Special case rotations +Matrix.RotationX = function(t) { + var c = Math.cos(t), s = Math.sin(t); + return Matrix.create([ + [1, 0, 0], + [0, c, -s], + [0, s, c] + ]); +}; + +Matrix.RotationY = function(t) { + var c = Math.cos(t), s = Math.sin(t); + return Matrix.create([ + [c, 0, s], + [0, 1, 0], + [-s, 0, c] + ]); +}; + +Matrix.RotationZ = function(t) { + var c = Math.cos(t), s = Math.sin(t); + return Matrix.create([ + [c, -s, 0], + [s, c, 0], + [0, 0, 1] + ]); +}; + +// Random matrix of n rows, m columns +Matrix.Random = function(n, m) { + if (arguments.length === 1) m = n; + return Matrix.Zero(n, m).map( + function() { return Math.random(); } + ); +}; + +Matrix.Fill = function(n, m, v) { + if (arguments.length === 2) { + v = m; + m = n; + } + + var els = [], i = n, j; + + while (i--) { + j = m; + els[i] = []; + + while (j--) { + els[i][j] = v; + } + } + + return Matrix.create(els); +}; + +// Matrix filled with zeros +Matrix.Zero = function(n, m) { + return Matrix.Fill(n, m, 0); +}; + +// Matrix filled with zeros +Matrix.Zeros = function(n, m) { + return Matrix.Zero(n, m); +}; + +// Matrix filled with ones +Matrix.One = function(n, m) { + return Matrix.Fill(n, m, 1); +}; + +// Matrix filled with ones +Matrix.Ones = function(n, m) { + return Matrix.One(n, m); +}; + +module.exports = Matrix; + +},{"./sylvester":17,"./vector":18,"fs":undefined}],16:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// Plane class - depends on Vector. Some methods require Matrix and Line. +var Vector = require('./vector'); +var Matrix = require('./matrix'); +var Line = require('./line'); + +var Sylvester = require('./sylvester'); + +function Plane() {} +Plane.prototype = { + + // Returns true iff the plane occupies the same space as the argument + eql: function(plane) { + return (this.contains(plane.anchor) && this.isParallelTo(plane)); + }, + + // Returns a copy of the plane + dup: function() { + return Plane.create(this.anchor, this.normal); + }, + + // Returns the result of translating the plane by the given vector + translate: function(vector) { + var V = vector.elements || vector; + return Plane.create([ + this.anchor.elements[0] + V[0], + this.anchor.elements[1] + V[1], + this.anchor.elements[2] + (V[2] || 0) + ], this.normal); + }, + + // Returns true iff the plane is parallel to the argument. Will return true + // if the planes are equal, or if you give a line and it lies in the plane. + isParallelTo: function(obj) { + var theta; + if (obj.normal) { + // obj is a plane + theta = this.normal.angleFrom(obj.normal); + return (Math.abs(theta) <= Sylvester.precision || Math.abs(Math.PI - theta) <= Sylvester.precision); + } else if (obj.direction) { + // obj is a line + return this.normal.isPerpendicularTo(obj.direction); + } + return null; + }, + + // Returns true iff the receiver is perpendicular to the argument + isPerpendicularTo: function(plane) { + var theta = this.normal.angleFrom(plane.normal); + return (Math.abs(Math.PI/2 - theta) <= Sylvester.precision); + }, + + // Returns the plane's distance from the given object (point, line or plane) + distanceFrom: function(obj) { + if (this.intersects(obj) || this.contains(obj)) { return 0; } + if (obj.anchor) { + // obj is a plane or line + var A = this.anchor.elements, B = obj.anchor.elements, N = this.normal.elements; + return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]); + } else { + // obj is a point + var P = obj.elements || obj; + var A = this.anchor.elements, N = this.normal.elements; + return Math.abs((A[0] - P[0]) * N[0] + (A[1] - P[1]) * N[1] + (A[2] - (P[2] || 0)) * N[2]); + } + }, + + // Returns true iff the plane contains the given point or line + contains: function(obj) { + if (obj.normal) { return null; } + if (obj.direction) { + return (this.contains(obj.anchor) && this.contains(obj.anchor.add(obj.direction))); + } else { + var P = obj.elements || obj; + var A = this.anchor.elements, N = this.normal.elements; + var diff = Math.abs(N[0]*(A[0] - P[0]) + N[1]*(A[1] - P[1]) + N[2]*(A[2] - (P[2] || 0))); + return (diff <= Sylvester.precision); + } + }, + + // Returns true iff the plane has a unique point/line of intersection with the argument + intersects: function(obj) { + if (typeof(obj.direction) == 'undefined' && typeof(obj.normal) == 'undefined') { return null; } + return !this.isParallelTo(obj); + }, + + // Returns the unique intersection with the argument, if one exists. The result + // will be a vector if a line is supplied, and a line if a plane is supplied. + intersectionWith: function(obj) { + if (!this.intersects(obj)) { return null; } + if (obj.direction) { + // obj is a line + var A = obj.anchor.elements, D = obj.direction.elements, + P = this.anchor.elements, N = this.normal.elements; + var multiplier = (N[0]*(P[0]-A[0]) + N[1]*(P[1]-A[1]) + N[2]*(P[2]-A[2])) / (N[0]*D[0] + N[1]*D[1] + N[2]*D[2]); + return Vector.create([A[0] + D[0]*multiplier, A[1] + D[1]*multiplier, A[2] + D[2]*multiplier]); + } else if (obj.normal) { + // obj is a plane + var direction = this.normal.cross(obj.normal).toUnitVector(); + // To find an anchor point, we find one co-ordinate that has a value + // of zero somewhere on the intersection, and remember which one we picked + var N = this.normal.elements, A = this.anchor.elements, + O = obj.normal.elements, B = obj.anchor.elements; + var solver = Matrix.Zero(2,2), i = 0; + while (solver.isSingular()) { + i++; + solver = Matrix.create([ + [ N[i%3], N[(i+1)%3] ], + [ O[i%3], O[(i+1)%3] ] + ]); + } + // Then we solve the simultaneous equations in the remaining dimensions + var inverse = solver.inverse().elements; + var x = N[0]*A[0] + N[1]*A[1] + N[2]*A[2]; + var y = O[0]*B[0] + O[1]*B[1] + O[2]*B[2]; + var intersection = [ + inverse[0][0] * x + inverse[0][1] * y, + inverse[1][0] * x + inverse[1][1] * y + ]; + var anchor = []; + for (var j = 1; j <= 3; j++) { + // This formula picks the right element from intersection by + // cycling depending on which element we set to zero above + anchor.push((i == j) ? 0 : intersection[(j + (5 - i)%3)%3]); + } + return Line.create(anchor, direction); + } + }, + + // Returns the point in the plane closest to the given point + pointClosestTo: function(point) { + var P = point.elements || point; + var A = this.anchor.elements, N = this.normal.elements; + var dot = (A[0] - P[0]) * N[0] + (A[1] - P[1]) * N[1] + (A[2] - (P[2] || 0)) * N[2]; + return Vector.create([P[0] + N[0] * dot, P[1] + N[1] * dot, (P[2] || 0) + N[2] * dot]); + }, + + // Returns a copy of the plane, rotated by t radians about the given line + // See notes on Line#rotate. + rotate: function(t, line) { + var R = t.determinant ? t.elements : Matrix.Rotation(t, line.direction).elements; + var C = line.pointClosestTo(this.anchor).elements; + var A = this.anchor.elements, N = this.normal.elements; + var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2]; + var x = A1 - C1, y = A2 - C2, z = A3 - C3; + return Plane.create([ + C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z, + C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z, + C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z + ], [ + R[0][0] * N[0] + R[0][1] * N[1] + R[0][2] * N[2], + R[1][0] * N[0] + R[1][1] * N[1] + R[1][2] * N[2], + R[2][0] * N[0] + R[2][1] * N[1] + R[2][2] * N[2] + ]); + }, + + // Returns the reflection of the plane in the given point, line or plane. + reflectionIn: function(obj) { + if (obj.normal) { + // obj is a plane + var A = this.anchor.elements, N = this.normal.elements; + var A1 = A[0], A2 = A[1], A3 = A[2], N1 = N[0], N2 = N[1], N3 = N[2]; + var newA = this.anchor.reflectionIn(obj).elements; + // Add the plane's normal to its anchor, then mirror that in the other plane + var AN1 = A1 + N1, AN2 = A2 + N2, AN3 = A3 + N3; + var Q = obj.pointClosestTo([AN1, AN2, AN3]).elements; + var newN = [Q[0] + (Q[0] - AN1) - newA[0], Q[1] + (Q[1] - AN2) - newA[1], Q[2] + (Q[2] - AN3) - newA[2]]; + return Plane.create(newA, newN); + } else if (obj.direction) { + // obj is a line + return this.rotate(Math.PI, obj); + } else { + // obj is a point + var P = obj.elements || obj; + return Plane.create(this.anchor.reflectionIn([P[0], P[1], (P[2] || 0)]), this.normal); + } + }, + + // Sets the anchor point and normal to the plane. If three arguments are specified, + // the normal is calculated by assuming the three points should lie in the same plane. + // If only two are sepcified, the second is taken to be the normal. Normal vector is + // normalised before storage. + setVectors: function(anchor, v1, v2) { + anchor = Vector.create(anchor); + anchor = anchor.to3D(); if (anchor === null) { return null; } + v1 = Vector.create(v1); + v1 = v1.to3D(); if (v1 === null) { return null; } + if (typeof(v2) == 'undefined') { + v2 = null; + } else { + v2 = Vector.create(v2); + v2 = v2.to3D(); if (v2 === null) { return null; } + } + var A1 = anchor.elements[0], A2 = anchor.elements[1], A3 = anchor.elements[2]; + var v11 = v1.elements[0], v12 = v1.elements[1], v13 = v1.elements[2]; + var normal, mod; + if (v2 !== null) { + var v21 = v2.elements[0], v22 = v2.elements[1], v23 = v2.elements[2]; + normal = Vector.create([ + (v12 - A2) * (v23 - A3) - (v13 - A3) * (v22 - A2), + (v13 - A3) * (v21 - A1) - (v11 - A1) * (v23 - A3), + (v11 - A1) * (v22 - A2) - (v12 - A2) * (v21 - A1) + ]); + mod = normal.modulus(); + if (mod === 0) { return null; } + normal = Vector.create([normal.elements[0] / mod, normal.elements[1] / mod, normal.elements[2] / mod]); + } else { + mod = Math.sqrt(v11*v11 + v12*v12 + v13*v13); + if (mod === 0) { return null; } + normal = Vector.create([v1.elements[0] / mod, v1.elements[1] / mod, v1.elements[2] / mod]); + } + this.anchor = anchor; + this.normal = normal; + return this; + } +}; + +// Constructor function +Plane.create = function(anchor, v1, v2) { + var P = new Plane(); + return P.setVectors(anchor, v1, v2); +}; + +// X-Y-Z planes +Plane.XY = Plane.create(Vector.Zero(3), Vector.k); +Plane.YZ = Plane.create(Vector.Zero(3), Vector.i); +Plane.ZX = Plane.create(Vector.Zero(3), Vector.j); +Plane.YX = Plane.XY; Plane.ZY = Plane.YZ; Plane.XZ = Plane.ZX; + +// Returns the plane containing the given points (can be arrays as +// well as vectors). If the points are not coplanar, returns null. +Plane.fromPoints = function(points) { + var np = points.length, list = [], i, P, n, N, A, B, C, D, theta, prevN, totalN = Vector.Zero(3); + for (i = 0; i < np; i++) { + P = Vector.create(points[i]).to3D(); + if (P === null) { return null; } + list.push(P); + n = list.length; + if (n > 2) { + // Compute plane normal for the latest three points + A = list[n-1].elements; B = list[n-2].elements; C = list[n-3].elements; + N = Vector.create([ + (A[1] - B[1]) * (C[2] - B[2]) - (A[2] - B[2]) * (C[1] - B[1]), + (A[2] - B[2]) * (C[0] - B[0]) - (A[0] - B[0]) * (C[2] - B[2]), + (A[0] - B[0]) * (C[1] - B[1]) - (A[1] - B[1]) * (C[0] - B[0]) + ]).toUnitVector(); + if (n > 3) { + // If the latest normal is not (anti)parallel to the previous one, we've strayed off the plane. + // This might be a slightly long-winded way of doing things, but we need the sum of all the normals + // to find which way the plane normal should point so that the points form an anticlockwise list. + theta = N.angleFrom(prevN); + if (theta !== null) { + if (!(Math.abs(theta) <= Sylvester.precision || Math.abs(theta - Math.PI) <= Sylvester.precision)) { return null; } + } + } + totalN = totalN.add(N); + prevN = N; + } + } + // We need to add in the normals at the start and end points, which the above misses out + A = list[1].elements; B = list[0].elements; C = list[n-1].elements; D = list[n-2].elements; + totalN = totalN.add(Vector.create([ + (A[1] - B[1]) * (C[2] - B[2]) - (A[2] - B[2]) * (C[1] - B[1]), + (A[2] - B[2]) * (C[0] - B[0]) - (A[0] - B[0]) * (C[2] - B[2]), + (A[0] - B[0]) * (C[1] - B[1]) - (A[1] - B[1]) * (C[0] - B[0]) + ]).toUnitVector()).add(Vector.create([ + (B[1] - C[1]) * (D[2] - C[2]) - (B[2] - C[2]) * (D[1] - C[1]), + (B[2] - C[2]) * (D[0] - C[0]) - (B[0] - C[0]) * (D[2] - C[2]), + (B[0] - C[0]) * (D[1] - C[1]) - (B[1] - C[1]) * (D[0] - C[0]) + ]).toUnitVector()); + return Plane.create(list[0], totalN); +}; + +module.exports = Plane; + +},{"./line":13,"./matrix":15,"./sylvester":17,"./vector":18}],17:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// This file is required in order for any other classes to work. Some Vector methods work with the +// other Sylvester classes and are useless unless they are included. Other classes such as Line and +// Plane will not function at all without Vector being loaded first. + +Math.sign = function(x) { + return x < 0 ? -1: 1; +} + +var Sylvester = { + precision: 1e-6, + approxPrecision: 1e-5 +}; + +module.exports = Sylvester; + +},{}],18:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// This file is required in order for any other classes to work. Some Vector methods work with the +// other Sylvester classes and are useless unless they are included. Other classes such as Line and +// Plane will not function at all without Vector being loaded first. + +var Sylvester = require('./sylvester'), +Matrix = require('./matrix'); + +function Vector() {} +Vector.prototype = { + + norm: function() { + var n = this.elements.length; + var sum = 0; + + while (n--) { + sum += Math.pow(this.elements[n], 2); + } + + return Math.sqrt(sum); + }, + + // Returns element i of the vector + e: function(i) { + return (i < 1 || i > this.elements.length) ? null : this.elements[i - 1]; + }, + + // Returns the number of rows/columns the vector has + dimensions: function() { + return {rows: 1, cols: this.elements.length}; + }, + + // Returns the number of rows in the vector + rows: function() { + return 1; + }, + + // Returns the number of columns in the vector + cols: function() { + return this.elements.length; + }, + + // Returns the modulus ('length') of the vector + modulus: function() { + return Math.sqrt(this.dot(this)); + }, + + // Returns true iff the vector is equal to the argument + eql: function(vector) { + var n = this.elements.length; + var V = vector.elements || vector; + if (n != V.length) { return false; } + while (n--) { + if (Math.abs(this.elements[n] - V[n]) > Sylvester.precision) { return false; } + } + return true; + }, + + // Returns a copy of the vector + dup: function() { + return Vector.create(this.elements); + }, + + // Maps the vector to another vector according to the given function + map: function(fn) { + var elements = []; + this.each(function(x, i) { + elements.push(fn(x, i)); + }); + return Vector.create(elements); + }, + + // Calls the iterator for each element of the vector in turn + each: function(fn) { + var n = this.elements.length; + for (var i = 0; i < n; i++) { + fn(this.elements[i], i + 1); + } + }, + + // Returns a new vector created by normalizing the receiver + toUnitVector: function() { + var r = this.modulus(); + if (r === 0) { return this.dup(); } + return this.map(function(x) { return x / r; }); + }, + + // Returns the angle between the vector and the argument (also a vector) + angleFrom: function(vector) { + var V = vector.elements || vector; + var n = this.elements.length, k = n, i; + if (n != V.length) { return null; } + var dot = 0, mod1 = 0, mod2 = 0; + // Work things out in parallel to save time + this.each(function(x, i) { + dot += x * V[i - 1]; + mod1 += x * x; + mod2 += V[i - 1] * V[i - 1]; + }); + mod1 = Math.sqrt(mod1); mod2 = Math.sqrt(mod2); + if (mod1 * mod2 === 0) { return null; } + var theta = dot / (mod1 * mod2); + if (theta < -1) { theta = -1; } + if (theta > 1) { theta = 1; } + return Math.acos(theta); + }, + + // Returns true iff the vector is parallel to the argument + isParallelTo: function(vector) { + var angle = this.angleFrom(vector); + return (angle === null) ? null : (angle <= Sylvester.precision); + }, + + // Returns true iff the vector is antiparallel to the argument + isAntiparallelTo: function(vector) { + var angle = this.angleFrom(vector); + return (angle === null) ? null : (Math.abs(angle - Math.PI) <= Sylvester.precision); + }, + + // Returns true iff the vector is perpendicular to the argument + isPerpendicularTo: function(vector) { + var dot = this.dot(vector); + return (dot === null) ? null : (Math.abs(dot) <= Sylvester.precision); + }, + + // Returns the result of adding the argument to the vector + add: function(value) { + var V = value.elements || value; + + if (this.elements.length != V.length) + return this.map(function(v) { return v + value }); + else + return this.map(function(x, i) { return x + V[i - 1]; }); + }, + + // Returns the result of subtracting the argument from the vector + subtract: function(v) { + if (typeof(v) == 'number') + return this.map(function(k) { return k - v; }); + + var V = v.elements || v; + if (this.elements.length != V.length) { return null; } + return this.map(function(x, i) { return x - V[i - 1]; }); + }, + + // Returns the result of multiplying the elements of the vector by the argument + multiply: function(k) { + return this.map(function(x) { return x * k; }); + }, + + elementMultiply: function(v) { + return this.map(function(k, i) { + return v.e(i) * k; + }); + }, + + sum: function() { + var sum = 0; + this.map(function(x) { sum += x;}); + return sum; + }, + + chomp: function(n) { + var elements = []; + + for (var i = n; i < this.elements.length; i++) { + elements.push(this.elements[i]); + } + + return Vector.create(elements); + }, + + top: function(n) { + var elements = []; + + for (var i = 0; i < n; i++) { + elements.push(this.elements[i]); + } + + return Vector.create(elements); + }, + + augment: function(elements) { + var newElements = this.elements; + + for (var i = 0; i < elements.length; i++) { + newElements.push(elements[i]); + } + + return Vector.create(newElements); + }, + + x: function(k) { return this.multiply(k); }, + + log: function() { + return Vector.log(this); + }, + + elementDivide: function(vector) { + return this.map(function(v, i) { + return v / vector.e(i); + }); + }, + + product: function() { + var p = 1; + + this.map(function(v) { + p *= v; + }); + + return p; + }, + + // Returns the scalar product of the vector with the argument + // Both vectors must have equal dimensionality + dot: function(vector) { + var V = vector.elements || vector; + var i, product = 0, n = this.elements.length; + if (n != V.length) { return null; } + while (n--) { product += this.elements[n] * V[n]; } + return product; + }, + + // Returns the vector product of the vector with the argument + // Both vectors must have dimensionality 3 + cross: function(vector) { + var B = vector.elements || vector; + if (this.elements.length != 3 || B.length != 3) { return null; } + var A = this.elements; + return Vector.create([ + (A[1] * B[2]) - (A[2] * B[1]), + (A[2] * B[0]) - (A[0] * B[2]), + (A[0] * B[1]) - (A[1] * B[0]) + ]); + }, + + // Returns the (absolute) largest element of the vector + max: function() { + var m = 0, i = this.elements.length; + while (i--) { + if (Math.abs(this.elements[i]) > Math.abs(m)) { m = this.elements[i]; } + } + return m; + }, + + + maxIndex: function() { + var m = 0, i = this.elements.length; + var maxIndex = -1; + + while (i--) { + if (Math.abs(this.elements[i]) > Math.abs(m)) { + m = this.elements[i]; + maxIndex = i + 1; + } + } + + return maxIndex; + }, + + + // Returns the index of the first match found + indexOf: function(x) { + var index = null, n = this.elements.length; + for (var i = 0; i < n; i++) { + if (index === null && this.elements[i] == x) { + index = i + 1; + } + } + return index; + }, + + // Returns a diagonal matrix with the vector's elements as its diagonal elements + toDiagonalMatrix: function() { + return Matrix.Diagonal(this.elements); + }, + + // Returns the result of rounding the elements of the vector + round: function() { + return this.map(function(x) { return Math.round(x); }); + }, + + // Transpose a Vector, return a 1xn Matrix + transpose: function() { + var rows = this.elements.length; + var elements = []; + + for (var i = 0; i < rows; i++) { + elements.push([this.elements[i]]); + } + return Matrix.create(elements); + }, + + // Returns a copy of the vector with elements set to the given value if they + // differ from it by less than Sylvester.precision + snapTo: function(x) { + return this.map(function(y) { + return (Math.abs(y - x) <= Sylvester.precision) ? x : y; + }); + }, + + // Returns the vector's distance from the argument, when considered as a point in space + distanceFrom: function(obj) { + if (obj.anchor || (obj.start && obj.end)) { return obj.distanceFrom(this); } + var V = obj.elements || obj; + if (V.length != this.elements.length) { return null; } + var sum = 0, part; + this.each(function(x, i) { + part = x - V[i - 1]; + sum += part * part; + }); + return Math.sqrt(sum); + }, + + // Returns true if the vector is point on the given line + liesOn: function(line) { + return line.contains(this); + }, + + // Return true iff the vector is a point in the given plane + liesIn: function(plane) { + return plane.contains(this); + }, + + // Rotates the vector about the given object. The object should be a + // point if the vector is 2D, and a line if it is 3D. Be careful with line directions! + rotate: function(t, obj) { + var V, R = null, x, y, z; + if (t.determinant) { R = t.elements; } + switch (this.elements.length) { + case 2: + V = obj.elements || obj; + if (V.length != 2) { return null; } + if (!R) { R = Matrix.Rotation(t).elements; } + x = this.elements[0] - V[0]; + y = this.elements[1] - V[1]; + return Vector.create([ + V[0] + R[0][0] * x + R[0][1] * y, + V[1] + R[1][0] * x + R[1][1] * y + ]); + break; + case 3: + if (!obj.direction) { return null; } + var C = obj.pointClosestTo(this).elements; + if (!R) { R = Matrix.Rotation(t, obj.direction).elements; } + x = this.elements[0] - C[0]; + y = this.elements[1] - C[1]; + z = this.elements[2] - C[2]; + return Vector.create([ + C[0] + R[0][0] * x + R[0][1] * y + R[0][2] * z, + C[1] + R[1][0] * x + R[1][1] * y + R[1][2] * z, + C[2] + R[2][0] * x + R[2][1] * y + R[2][2] * z + ]); + break; + default: + return null; + } + }, + + // Returns the result of reflecting the point in the given point, line or plane + reflectionIn: function(obj) { + if (obj.anchor) { + // obj is a plane or line + var P = this.elements.slice(); + var C = obj.pointClosestTo(P).elements; + return Vector.create([C[0] + (C[0] - P[0]), C[1] + (C[1] - P[1]), C[2] + (C[2] - (P[2] || 0))]); + } else { + // obj is a point + var Q = obj.elements || obj; + if (this.elements.length != Q.length) { return null; } + return this.map(function(x, i) { return Q[i - 1] + (Q[i - 1] - x); }); + } + }, + + // Utility to make sure vectors are 3D. If they are 2D, a zero z-component is added + to3D: function() { + var V = this.dup(); + switch (V.elements.length) { + case 3: break; + case 2: V.elements.push(0); break; + default: return null; + } + return V; + }, + + // Returns a string representation of the vector + inspect: function() { + return '[' + this.elements.join(', ') + ']'; + }, + + // Set vector's elements from an array + setElements: function(els) { + this.elements = (els.elements || els).slice(); + return this; + } +}; + +// Constructor function +Vector.create = function(elements) { + var V = new Vector(); + return V.setElements(elements); +}; + +// i, j, k unit vectors +Vector.i = Vector.create([1, 0, 0]); +Vector.j = Vector.create([0, 1, 0]); +Vector.k = Vector.create([0, 0, 1]); + +// Random vector of size n +Vector.Random = function(n) { + var elements = []; + while (n--) { elements.push(Math.random()); } + return Vector.create(elements); +}; + +Vector.Fill = function(n, v) { + var elements = []; + while (n--) { elements.push(v); } + return Vector.create(elements); +}; + +// Vector filled with zeros +Vector.Zero = function(n) { + return Vector.Fill(n, 0); +}; + +Vector.One = function(n) { + return Vector.Fill(n, 1); +}; + +Vector.log = function(v) { + return v.map(function(x) { + return Math.log(x); + }); +}; + +module.exports = Vector; + +},{"./matrix":15,"./sylvester":17}],19:[function(require,module,exports){ +"use strict"; + +/** + * Represents a 2-dimensional size value. + */ + +function Size(w, h) { + this.w = w; + this.h = h; +} + +Size.prototype = { + toString: function () { + return "(" + this.w + ", " + this.h + ")"; + }, + getHalfSize: function() { + return new Size(this.w >>> 1, this.h >>> 1); + }, + length: function() { + return this.w * this.h; + } +} +module.exports = Size; +},{}],20:[function(require,module,exports){ +"use strict"; + +var error = require('./error'); + +function assert(condition, message) { + if (!condition) { + error(message); + } +} + + +module.exports = assert; + +},{"./error":21}],21:[function(require,module,exports){ +"use strict"; + +function error(message) { + console.error(message); + console.trace(); +} + +module.exports = error; + +},{}],22:[function(require,module,exports){ +"use strict"; + +var Matrix = require('sylvester.js').Matrix; +var Vector = require('sylvester.js').Vector; +var $M = Matrix.create; + + +// augment Sylvester some +Matrix.Translation = function (v) +{ + if (v.elements.length == 2) { + var r = Matrix.I(3); + r.elements[2][0] = v.elements[0]; + r.elements[2][1] = v.elements[1]; + return r; + } + + if (v.elements.length == 3) { + var r = Matrix.I(4); + r.elements[0][3] = v.elements[0]; + r.elements[1][3] = v.elements[1]; + r.elements[2][3] = v.elements[2]; + return r; + } + + throw "Invalid length for Translation"; +} + +Matrix.prototype.flatten = function () +{ + var result = []; + if (this.elements.length == 0) + return []; + + + for (var j = 0; j < this.elements[0].length; j++) + for (var i = 0; i < this.elements.length; i++) + result.push(this.elements[i][j]); + return result; +} + +Matrix.prototype.ensure4x4 = function() +{ + if (this.elements.length == 4 && + this.elements[0].length == 4) + return this; + + if (this.elements.length > 4 || + this.elements[0].length > 4) + return null; + + for (var i = 0; i < this.elements.length; i++) { + for (var j = this.elements[i].length; j < 4; j++) { + if (i == j) + this.elements[i].push(1); + else + this.elements[i].push(0); + } + } + + for (var i = this.elements.length; i < 4; i++) { + if (i == 0) + this.elements.push([1, 0, 0, 0]); + else if (i == 1) + this.elements.push([0, 1, 0, 0]); + else if (i == 2) + this.elements.push([0, 0, 1, 0]); + else if (i == 3) + this.elements.push([0, 0, 0, 1]); + } + + return this; +}; + + +Vector.prototype.flatten = function () +{ + return this.elements; +}; + + + +// +// gluPerspective +// +function makePerspective(fovy, aspect, znear, zfar) +{ + var ymax = znear * Math.tan(fovy * Math.PI / 360.0); + var ymin = -ymax; + var xmin = ymin * aspect; + var xmax = ymax * aspect; + + return makeFrustum(xmin, xmax, ymin, ymax, znear, zfar); +} + +// +// glFrustum +// +function makeFrustum(left, right, + bottom, top, + znear, zfar) +{ + var X = 2*znear/(right-left); + var Y = 2*znear/(top-bottom); + var A = (right+left)/(right-left); + var B = (top+bottom)/(top-bottom); + var C = -(zfar+znear)/(zfar-znear); + var D = -2*zfar*znear/(zfar-znear); + + return $M([[X, 0, A, 0], + [0, Y, B, 0], + [0, 0, C, D], + [0, 0, -1, 0]]); +} + +module.exports.makePerspective = makePerspective; + + +},{"sylvester.js":12}],23:[function(require,module,exports){ +"use strict"; + +var Avc = require('../broadway/Decoder'); +var YUVWebGLCanvas = require('../canvas/YUVWebGLCanvas'); +var YUVCanvas = require('../canvas/YUVCanvas'); +var Size = require('../utils/Size'); +var Class = require('uclass'); +var Events = require('uclass/events'); +var debug = require('debug'); +var log = debug("wsavc"); + +var WSAvcPlayer = new Class({ + Implements : [Events], + + + initialize : function(canvas, canvastype) { + + this.canvas = canvas; + this.canvastype = canvastype; + + // AVC codec initialization + this.avc = new Avc(); + if(false) this.avc.configure({ + filter: "original", + filterHorLuma: "optimized", + filterVerLumaEdge: "optimized", + getBoundaryStrengthsA: "optimized" + }); + + //WebSocket variable + this.ws; + this.pktnum = 0; + + }, + + + decode : function(data) { + var naltype = "invalid frame"; + + if (data.length > 4) { + if (data[4] == 0x65) { + naltype = "I frame"; + } + else if (data[4] == 0x41) { + naltype = "P frame"; + } + else if (data[4] == 0x67) { + naltype = "SPS"; + } + else if (data[4] == 0x68) { + naltype = "PPS"; + } + } + //log("Passed " + naltype + " to decoder"); + this.avc.decode(data); + }, + + connect : function(url) { + + // Websocket initialization + if (this.ws != undefined) { + this.ws.close(); + delete this.ws; + } + this.ws = new WebSocket(url); + this.ws.binaryType = "arraybuffer"; + + this.ws.onopen = () => { + log("Connected to " + url); + }; + + + var framesList = []; + + this.ws.onmessage = (evt) => { + if(typeof evt.data == "string") + return this.cmd(JSON.parse(evt.data)); + + this.pktnum++; + var frame = new Uint8Array(evt.data); + //log("[Pkt " + this.pktnum + " (" + evt.data.byteLength + " bytes)]"); + //this.decode(frame); + framesList.push(frame); + }; + + + var running = true; + + var shiftFrame = function() { + if(!running) + return; + + + if(framesList.length > 10) { + log("Dropping frames", framesList.length); + framesList = []; + } + + var frame = framesList.shift(); + + + if(frame) + this.decode(frame); + + requestAnimationFrame(shiftFrame); + }.bind(this); + + + shiftFrame(); + + + + this.ws.onclose = () => { + running = false; + log("WSAvcPlayer: Connection closed") + }; + + }, + + initCanvas : function(width, height) { + var canvasFactory = this.canvastype == "webgl" || this.canvastype == "YUVWebGLCanvas" + ? YUVWebGLCanvas + : YUVCanvas; + + var canvas = new canvasFactory(this.canvas, new Size(width, height)); + this.avc.onPictureDecoded = canvas.decode; + this.emit("canvasReady", width, height); + }, + + cmd : function(cmd){ + log("Incoming request", cmd); + + if(cmd.action == "init") { + this.initCanvas(cmd.width, cmd.height); + this.canvas.width = cmd.width; + this.canvas.height = cmd.height; + } + }, + + disconnect : function() { + this.ws.close(); + }, + + playStream : function() { + var message = "REQUESTSTREAM "; + this.ws.send(message); + log("Sent " + message); + }, + + + stopStream : function() { + this.ws.send("STOPSTREAM"); + log("Sent STOPSTREAM"); + }, +}); + + +module.exports = WSAvcPlayer; +module.exports.debug = debug; + +},{"../broadway/Decoder":4,"../canvas/YUVCanvas":10,"../canvas/YUVWebGLCanvas":11,"../utils/Size":19,"debug":1,"uclass":47,"uclass/events":24}],24:[function(require,module,exports){ +"use strict"; + +var Class = require('../'); +var guid = require('mout/random/guid'); +var forIn = require('mout/object/forIn'); + +var EventEmitter = new Class({ + Binds : ['on', 'off', 'once', 'emit'], + + callbacks : {}, + + initialize : function() { + var self = this; + this.addEvent = this.on; + this.removeListener = this.off; + this.removeAllListeners = this.off; + this.fireEvent = this.emit; + }, + + emit:function(event, payload){ + if(!this.callbacks[event]) + return; + + var args = Array.prototype.slice.call(arguments, 1); + + forIn(this.callbacks[event], function(callback){ + callback.apply(null, args); + }); + }, + + + on:function(event, callback){ + if(typeof callback != "function") + return console.log("you try to register a non function in " , event) + if(!this.callbacks[event]) + this.callbacks[event] = {}; + this.callbacks[event][guid()] = callback; + }, + + once:function(event, callback){ + var self = this; + var once = function(){ + self.off(event, once); + self.off(event, callback); + }; + + this.on(event, callback); + this.on(event, once); + }, + + off:function(event, callback){ + if(!event) + this.callbacks = {}; + else if(!callback) + this.callbacks[event] = {}; + else forIn(this.callbacks[event] || {}, function(v, k) { + if(v == callback) + delete this.callbacks[event][k]; + }, this); + }, +}); + +module.exports = EventEmitter; +},{"../":47,"mout/object/forIn":36,"mout/random/guid":42}],25:[function(require,module,exports){ +"use strict"; + +var verbs = /^Implements|Extends|Binds$/ + +module.exports = function(ctx, obj){ + for(var key in obj) { + if(key.match(verbs)) continue; + if((typeof obj[key] == 'function') && obj[key].$static) + ctx[key] = obj[key]; + else + ctx.prototype[key] = obj[key]; + } + return ctx; +} +},{}],26:[function(require,module,exports){ +var kindOf = require('./kindOf'); +var isPlainObject = require('./isPlainObject'); +var mixIn = require('../object/mixIn'); + + /** + * Clone native types. + */ + function clone(val){ + switch (kindOf(val)) { + case 'Object': + return cloneObject(val); + case 'Array': + return cloneArray(val); + case 'RegExp': + return cloneRegExp(val); + case 'Date': + return cloneDate(val); + default: + return val; + } + } + + function cloneObject(source) { + if (isPlainObject(source)) { + return mixIn({}, source); + } else { + return source; + } + } + + function cloneRegExp(r) { + var flags = ''; + flags += r.multiline ? 'm' : ''; + flags += r.global ? 'g' : ''; + flags += r.ignoreCase ? 'i' : ''; + return new RegExp(r.source, flags); + } + + function cloneDate(date) { + return new Date(+date); + } + + function cloneArray(arr) { + return arr.slice(); + } + + module.exports = clone; + + + +},{"../object/mixIn":40,"./isPlainObject":32,"./kindOf":33}],27:[function(require,module,exports){ +var mixIn = require('../object/mixIn'); + + /** + * Create Object using prototypal inheritance and setting custom properties. + * - Mix between Douglas Crockford Prototypal Inheritance and the EcmaScript 5 `Object.create()` method. + * @param {object} parent Parent Object. + * @param {object} [props] Object properties. + * @return {object} Created object. + */ + function createObject(parent, props){ + function F(){} + F.prototype = parent; + return mixIn(new F(), props); + + } + module.exports = createObject; + + + +},{"../object/mixIn":40}],28:[function(require,module,exports){ +var clone = require('./clone'); +var forOwn = require('../object/forOwn'); +var kindOf = require('./kindOf'); +var isPlainObject = require('./isPlainObject'); + + /** + * Recursively clone native types. + */ + function deepClone(val, instanceClone) { + switch ( kindOf(val) ) { + case 'Object': + return cloneObject(val, instanceClone); + case 'Array': + return cloneArray(val, instanceClone); + default: + return clone(val); + } + } + + function cloneObject(source, instanceClone) { + if (isPlainObject(source)) { + var out = {}; + forOwn(source, function(val, key) { + this[key] = deepClone(val, instanceClone); + }, out); + return out; + } else if (instanceClone) { + return instanceClone(source); + } else { + return source; + } + } + + function cloneArray(arr, instanceClone) { + var out = [], + i = -1, + n = arr.length, + val; + while (++i < n) { + out[i] = deepClone(arr[i], instanceClone); + } + return out; + } + + module.exports = deepClone; + + + + +},{"../object/forOwn":37,"./clone":26,"./isPlainObject":32,"./kindOf":33}],29:[function(require,module,exports){ +var isKind = require('./isKind'); + /** + */ + var isArray = Array.isArray || function (val) { + return isKind(val, 'Array'); + }; + module.exports = isArray; + + +},{"./isKind":30}],30:[function(require,module,exports){ +var kindOf = require('./kindOf'); + /** + * Check if value is from a specific "kind". + */ + function isKind(val, kind){ + return kindOf(val) === kind; + } + module.exports = isKind; + + +},{"./kindOf":33}],31:[function(require,module,exports){ +var isKind = require('./isKind'); + /** + */ + function isObject(val) { + return isKind(val, 'Object'); + } + module.exports = isObject; + + +},{"./isKind":30}],32:[function(require,module,exports){ + + + /** + * Checks if the value is created by the `Object` constructor. + */ + function isPlainObject(value) { + return (!!value && typeof value === 'object' && + value.constructor === Object); + } + + module.exports = isPlainObject; + + + +},{}],33:[function(require,module,exports){ + + + var _rKind = /^\[object (.*)\]$/, + _toString = Object.prototype.toString, + UNDEF; + + /** + * Gets the "kind" of value. (e.g. "String", "Number", etc) + */ + function kindOf(val) { + if (val === null) { + return 'Null'; + } else if (val === UNDEF) { + return 'Undefined'; + } else { + return _rKind.exec( _toString.call(val) )[1]; + } + } + module.exports = kindOf; + + +},{}],34:[function(require,module,exports){ +/** + * @constant Maximum 32-bit signed integer value. (2^31 - 1) + */ + + module.exports = 2147483647; + + +},{}],35:[function(require,module,exports){ +/** + * @constant Minimum 32-bit signed integer value (-2^31). + */ + + module.exports = -2147483648; + + +},{}],36:[function(require,module,exports){ +var hasOwn = require('./hasOwn'); + + var _hasDontEnumBug, + _dontEnums; + + function checkDontEnum(){ + _dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' + ]; + + _hasDontEnumBug = true; + + for (var key in {'toString': null}) { + _hasDontEnumBug = false; + } + } + + /** + * Similar to Array/forEach but works over object properties and fixes Don't + * Enum bug on IE. + * based on: http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation + */ + function forIn(obj, fn, thisObj){ + var key, i = 0; + // no need to check if argument is a real object that way we can use + // it for arrays, functions, date, etc. + + //post-pone check till needed + if (_hasDontEnumBug == null) checkDontEnum(); + + for (key in obj) { + if (exec(fn, obj, key, thisObj) === false) { + break; + } + } + + + if (_hasDontEnumBug) { + var ctor = obj.constructor, + isProto = !!ctor && obj === ctor.prototype; + + while (key = _dontEnums[i++]) { + // For constructor, if it is a prototype object the constructor + // is always non-enumerable unless defined otherwise (and + // enumerated above). For non-prototype objects, it will have + // to be defined on this object, since it cannot be defined on + // any prototype objects. + // + // For other [[DontEnum]] properties, check if the value is + // different than Object prototype value. + if ( + (key !== 'constructor' || + (!isProto && hasOwn(obj, key))) && + obj[key] !== Object.prototype[key] + ) { + if (exec(fn, obj, key, thisObj) === false) { + break; + } + } + } + } + } + + function exec(fn, obj, key, thisObj){ + return fn.call(thisObj, obj[key], key, obj); + } + + module.exports = forIn; + + + +},{"./hasOwn":38}],37:[function(require,module,exports){ +var hasOwn = require('./hasOwn'); +var forIn = require('./forIn'); + + /** + * Similar to Array/forEach but works over object properties and fixes Don't + * Enum bug on IE. + * based on: http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation + */ + function forOwn(obj, fn, thisObj){ + forIn(obj, function(val, key){ + if (hasOwn(obj, key)) { + return fn.call(thisObj, obj[key], key, obj); + } + }); + } + + module.exports = forOwn; + + + +},{"./forIn":36,"./hasOwn":38}],38:[function(require,module,exports){ + + + /** + * Safer Object.hasOwnProperty + */ + function hasOwn(obj, prop){ + return Object.prototype.hasOwnProperty.call(obj, prop); + } + + module.exports = hasOwn; + + + +},{}],39:[function(require,module,exports){ +var hasOwn = require('./hasOwn'); +var deepClone = require('../lang/deepClone'); +var isObject = require('../lang/isObject'); + + /** + * Deep merge objects. + */ + function merge() { + var i = 1, + key, val, obj, target; + + // make sure we don't modify source element and it's properties + // objects are passed by reference + target = deepClone( arguments[0] ); + + while (obj = arguments[i++]) { + for (key in obj) { + if ( ! hasOwn(obj, key) ) { + continue; + } + + val = obj[key]; + + if ( isObject(val) && isObject(target[key]) ){ + // inception, deep merge objects + target[key] = merge(target[key], val); + } else { + // make sure arrays, regexp, date, objects are cloned + target[key] = deepClone(val); + } + + } + } + + return target; + } + + module.exports = merge; + + + +},{"../lang/deepClone":28,"../lang/isObject":31,"./hasOwn":38}],40:[function(require,module,exports){ +var forOwn = require('./forOwn'); + + /** + * Combine properties from all the objects into first one. + * - This method affects target object in place, if you want to create a new Object pass an empty object as first param. + * @param {object} target Target Object + * @param {...object} objects Objects to be combined (0...n objects). + * @return {object} Target Object. + */ + function mixIn(target, objects){ + var i = 0, + n = arguments.length, + obj; + while(++i < n){ + obj = arguments[i]; + if (obj != null) { + forOwn(obj, copyProp, target); + } + } + return target; + } + + function copyProp(val, key){ + this[key] = val; + } + + module.exports = mixIn; + + +},{"./forOwn":37}],41:[function(require,module,exports){ +var randInt = require('./randInt'); +var isArray = require('../lang/isArray'); + + /** + * Returns a random element from the supplied arguments + * or from the array (if single argument is an array). + */ + function choice(items) { + var target = (arguments.length === 1 && isArray(items))? items : arguments; + return target[ randInt(0, target.length - 1) ]; + } + + module.exports = choice; + + + +},{"../lang/isArray":29,"./randInt":45}],42:[function(require,module,exports){ +var randHex = require('./randHex'); +var choice = require('./choice'); + + /** + * Returns pseudo-random guid (UUID v4) + * IMPORTANT: it's not totally "safe" since randHex/choice uses Math.random + * by default and sequences can be predicted in some cases. See the + * "random/random" documentation for more info about it and how to replace + * the default PRNG. + */ + function guid() { + return ( + randHex(8)+'-'+ + randHex(4)+'-'+ + // v4 UUID always contain "4" at this position to specify it was + // randomly generated + '4' + randHex(3) +'-'+ + // v4 UUID always contain chars [a,b,8,9] at this position + choice(8, 9, 'a', 'b') + randHex(3)+'-'+ + randHex(12) + ); + } + module.exports = guid; + + +},{"./choice":41,"./randHex":44}],43:[function(require,module,exports){ +var random = require('./random'); +var MIN_INT = require('../number/MIN_INT'); +var MAX_INT = require('../number/MAX_INT'); + + /** + * Returns random number inside range + */ + function rand(min, max){ + min = min == null? MIN_INT : min; + max = max == null? MAX_INT : max; + return min + (max - min) * random(); + } + + module.exports = rand; + + +},{"../number/MAX_INT":34,"../number/MIN_INT":35,"./random":46}],44:[function(require,module,exports){ +var choice = require('./choice'); + + var _chars = '0123456789abcdef'.split(''); + + /** + * Returns a random hexadecimal string + */ + function randHex(size){ + size = size && size > 0? size : 6; + var str = ''; + while (size--) { + str += choice(_chars); + } + return str; + } + + module.exports = randHex; + + + +},{"./choice":41}],45:[function(require,module,exports){ +var MIN_INT = require('../number/MIN_INT'); +var MAX_INT = require('../number/MAX_INT'); +var rand = require('./rand'); + + /** + * Gets random integer inside range or snap to min/max values. + */ + function randInt(min, max){ + min = min == null? MIN_INT : ~~min; + max = max == null? MAX_INT : ~~max; + // can't be max + 0.5 otherwise it will round up if `rand` + // returns `max` causing it to overflow range. + // -0.5 and + 0.49 are required to avoid bias caused by rounding + return Math.round( rand(min - 0.5, max + 0.499999999999) ); + } + + module.exports = randInt; + + +},{"../number/MAX_INT":34,"../number/MIN_INT":35,"./rand":43}],46:[function(require,module,exports){ + + + /** + * Just a wrapper to Math.random. No methods inside mout/random should call + * Math.random() directly so we can inject the pseudo-random number + * generator if needed (ie. in case we need a seeded random or a better + * algorithm than the native one) + */ + function random(){ + return random.get(); + } + + // we expose the method so it can be swapped if needed + random.get = Math.random; + + module.exports = random; + + + +},{}],47:[function(require,module,exports){ +"use strict"; + +var hasOwn = require("mout/object/hasOwn"); +var create = require("mout/lang/createObject"); +var merge = require("mout/object/merge"); +var kindOf = require("mout/lang/kindOf"); +var mixIn = require("mout/object/mixIn"); + +var implement = require('./implement'); +var verbs = /^Implements|Extends|Binds$/ + + + + +var uClass = function(proto){ + + if(kindOf(proto) === "Function") proto = {initialize: proto}; + + var superprime = proto.Extends; + + var constructor = (hasOwn(proto, "initialize")) ? proto.initialize : superprime ? superprime : function(){}; + + + + var out = function() { + var self = this; + //autobinding takes place here + if(proto.Binds) proto.Binds.forEach(function(f){ + var original = self[f]; + if(original) + self[f] = mixIn(self[f].bind(self), original); + }); + + //clone non function/static properties to current instance + for(var key in out.prototype) { + var v = out.prototype[key], t = kindOf(v); + + if(key.match(verbs) || t === "Function" || t == "GeneratorFunction") + continue; + + if(t == "Object") + self[key] = merge({}, self[key]); //create(null, self[key]); + else if(t == "Array") + self[key] = v.slice(); //clone ?? + else + self[key] = v; + } + + if(proto.Implements) + proto.Implements.forEach(function(Mixin){ + Mixin.call(self); + }); + + + + + constructor.apply(this, arguments); + } + + + if (superprime) { + // inherit from superprime + var superproto = superprime.prototype; + if(superproto.Binds) + proto.Binds = (proto.Binds || []).concat(superproto.Binds); + + if(superproto.Implements) + proto.Implements = (proto.Implements || []).concat(superproto.Implements); + + var cproto = out.prototype = create(superproto); + // setting constructor.parent to superprime.prototype + // because it's the shortest possible absolute reference + out.parent = superproto; + cproto.constructor = out + + } + + + if(proto.Implements) { + if (kindOf(proto.Implements) !== "Array") + proto.Implements = [proto.Implements]; + proto.Implements.forEach(function(Mixin){ + implement(out, Mixin.prototype); + }); + } + + implement(out, proto); + if(proto.Binds) + out.prototype.Binds = proto.Binds; + if(proto.Implements) + out.prototype.Implements = proto.Implements; + + return out; +}; + + + +module.exports = uClass; +},{"./implement":25,"mout/lang/createObject":27,"mout/lang/kindOf":33,"mout/object/hasOwn":38,"mout/object/merge":39,"mout/object/mixIn":40}]},{},[23])(23) +}); \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/h264liveplayer/http-live-player.js b/tools/ffmpegToWeb/Player/broadway/h264liveplayer/http-live-player.js new file mode 100644 index 0000000..7021af6 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/h264liveplayer/http-live-player.js @@ -0,0 +1,5186 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.WSAvcPlayer = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +function useColors() { + // is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + return (typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style) || + // is firebug? http://stackoverflow.com/a/398120/376773 + (window.console && (console.firebug || (console.exception && console.table))) || + // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); +} + +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +exports.formatters.j = function(v) { + return JSON.stringify(v); +}; + + +/** + * Colorize log arguments if enabled. + * + * @api public + */ + +function formatArgs() { + var args = arguments; + var useColors = this.useColors; + + args[0] = (useColors ? '%c' : '') + + this.namespace + + (useColors ? ' %c' : ' ') + + args[0] + + (useColors ? '%c ' : ' ') + + '+' + exports.humanize(this.diff); + + if (!useColors) return args; + + var c = 'color: ' + this.color; + args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); + + // the final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + var index = 0; + var lastC = 0; + args[0].replace(/%[a-z%]/g, function(match) { + if ('%%' === match) return; + index++; + if ('%c' === match) { + // we only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + + args.splice(lastC, 0, c); + return args; +} + +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". + * + * @api public + */ + +function log() { + // this hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return 'object' === typeof console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + +function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch(e) {} +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + var r; + try { + r = exports.storage.debug; + } catch(e) {} + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if ('env' in (typeof process === 'undefined' ? {} : process)) { + r = process.env.DEBUG; + } + + return r; +} + +/** + * Enable namespaces listed in `localStorage.debug` initially. + */ + +exports.enable(load()); + +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + +function localstorage(){ + try { + return window.localStorage; + } catch (e) {} +} + +},{"./debug":2}],2:[function(require,module,exports){ + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = debug.debug = debug; +exports.coerce = coerce; +exports.disable = disable; +exports.enable = enable; +exports.enabled = enabled; +exports.humanize = require('ms'); + +/** + * The currently active debug mode names, and names to skip. + */ + +exports.names = []; +exports.skips = []; + +/** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lowercased letter, i.e. "n". + */ + +exports.formatters = {}; + +/** + * Previously assigned color. + */ + +var prevColor = 0; + +/** + * Previous log timestamp. + */ + +var prevTime; + +/** + * Select a color. + * + * @return {Number} + * @api private + */ + +function selectColor() { + return exports.colors[prevColor++ % exports.colors.length]; +} + +/** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + +function debug(namespace) { + + // define the `disabled` version + function disabled() { + } + disabled.enabled = false; + + // define the `enabled` version + function enabled() { + + var self = enabled; + + // set `diff` timestamp + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + + // add the `color` if not set + if (null == self.useColors) self.useColors = exports.useColors(); + if (null == self.color && self.useColors) self.color = selectColor(); + + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + + args[0] = exports.coerce(args[0]); + + if ('string' !== typeof args[0]) { + // anything else let's inspect with %o + args = ['%o'].concat(args); + } + + // apply any `formatters` transformations + var index = 0; + args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { + // if we encounter an escaped % then don't increase the array index + if (match === '%%') return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); + + // now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + // apply env-specific formatting + args = exports.formatArgs.apply(self, args); + + var logFn = enabled.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } + enabled.enabled = true; + + var fn = exports.enabled(namespace) ? enabled : disabled; + + fn.namespace = namespace; + + return fn; +} + +/** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + +function enable(namespaces) { + exports.save(namespaces); + + var split = (namespaces || '').split(/[\s,]+/); + var len = split.length; + + for (var i = 0; i < len; i++) { + if (!split[i]) continue; // ignore empty strings + namespaces = split[i].replace(/[\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } + } +} + +/** + * Disable debug output. + * + * @api public + */ + +function disable() { + exports.enable(''); +} + +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + +function enabled(name) { + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; +} + +/** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} + +},{"ms":3}],3:[function(require,module,exports){ +/** + * Helpers. + */ + +var s = 1000 +var m = s * 60 +var h = m * 60 +var d = h * 24 +var y = d * 365.25 + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} options + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ + +module.exports = function (val, options) { + options = options || {} + var type = typeof val + if (type === 'string' && val.length > 0) { + return parse(val) + } else if (type === 'number' && isNaN(val) === false) { + return options.long ? + fmtLong(val) : + fmtShort(val) + } + throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val)) +} + +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function parse(str) { + str = String(str) + if (str.length > 10000) { + return + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str) + if (!match) { + return + } + var n = parseFloat(match[1]) + var type = (match[2] || 'ms').toLowerCase() + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y + case 'days': + case 'day': + case 'd': + return n * d + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n + default: + return undefined + } +} + +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd' + } + if (ms >= h) { + return Math.round(ms / h) + 'h' + } + if (ms >= m) { + return Math.round(ms / m) + 'm' + } + if (ms >= s) { + return Math.round(ms / s) + 's' + } + return ms + 'ms' +} + +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtLong(ms) { + return plural(ms, d, 'day') || + plural(ms, h, 'hour') || + plural(ms, m, 'minute') || + plural(ms, s, 'second') || + ms + ' ms' +} + +/** + * Pluralization helper. + */ + +function plural(ms, n, name) { + if (ms < n) { + return + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name + } + return Math.ceil(ms / n) + ' ' + name + 's' +} + +},{}],4:[function(require,module,exports){ +(function (__dirname){ +// universal module definition +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], factory); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.Decoder = factory(); + } +}(this, function () { + + var global; + + function initglobal(){ + global = this; + if (!global){ + if (typeof window != "undefined"){ + global = window; + }else if (typeof self != "undefined"){ + global = self; + }; + }; + }; + initglobal(); + + + function error(message) { + console.error(message); + console.trace(); + }; + + + function assert(condition, message) { + if (!condition) { + error(message); + }; + }; + + + return (function(){ + "use strict"; + + + + + var getModule = function(_broadwayOnHeadersDecoded, _broadwayOnPictureDecoded){ + + var window = this; + //console.log(typeof window); + + window._broadwayOnHeadersDecoded = _broadwayOnHeadersDecoded; + window._broadwayOnPictureDecoded = _broadwayOnPictureDecoded; + + var Module = { + 'print': function(text) { console.log('stdout: ' + text); }, + 'printErr': function(text) { console.log('stderr: ' + text); } + }; + + + /* + + The reason why this is all packed into one file is that this file can also function as worker. + you can integrate the file into your build system and provide the original file to be loaded into a worker. + + */ + +function d(a){throw a;}var g=void 0,i=!0,k=null,m=!1;function n(){return function(){}}var p;p||(p=eval("(function() { try { return Module || {} } catch(e) { return {} } })()"));var aa={},r;for(r in p)p.hasOwnProperty(r)&&(aa[r]=p[r]);var t="object"===typeof process&&"function"===typeof null,ba="object"===typeof window,ca="function"===typeof importScripts,da=!ba&&!t&&!ca; +if(t){p.print||(p.print=function(a){process.stdout.write(a+"\n")});p.printErr||(p.printErr=function(a){process.stderr.write(a+"\n")});var fa=(null)("fs"),ga=(null)("path");p.read=function(a,b){var a=ga.normalize(a),c=fa.readFileSync(a);!c&&a!=ga.resolve(a)&&(a=path.join(__dirname,"..","src",a),c=fa.readFileSync(a));c&&!b&&(c=c.toString());return c};p.readBinary=function(a){return p.read(a,i)};p.load=function(a){ha(read(a))};p.thisProgram=1 0) var gc = undefined")):ba||ca?(p.read=function(a){var b=new XMLHttpRequest;b.open("GET",a,m);b.send(k);return b.responseText},"undefined"!=typeof arguments&&(p.arguments=arguments),"undefined"!==typeof console?(p.print||(p.print=function(a){console.log(a)}),p.printErr||(p.printErr=function(a){console.log(a)})):p.print||(p.print= +n()),ba?window.Module=p:p.load=importScripts):d("Unknown runtime environment. Where are we?");function ha(a){eval.call(k,a)}!p.load&&p.read&&(p.load=function(a){ha(p.read(a))});p.print||(p.print=n());p.printErr||(p.printErr=p.print);p.arguments||(p.arguments=[]);p.thisProgram||(p.thisProgram="./this.program");p.print=p.print;p.fa=p.printErr;p.preRun=[];p.postRun=[];for(r in aa)aa.hasOwnProperty(r)&&(p[r]=aa[r]); +var z={Yd:function(a){ja=a},xd:function(){return ja},Tb:function(){return y},Sb:function(a){y=a},oc:function(a){switch(a){case "i1":case "i8":return 1;case "i16":return 2;case "i32":return 4;case "i64":return 8;case "float":return 4;case "double":return 8;default:return"*"===a[a.length-1]?z.ia:"i"===a[0]?(a=parseInt(a.substr(1)),w(0===a%8),a/8):0}},vd:function(a){return Math.max(z.oc(a),z.ia)},Qf:16,ng:function(a,b,c){return!c&&("i64"==a||"double"==a)?8:!a?Math.min(b,8):Math.min(b||(a?z.vd(a):0), +z.ia)},Fa:function(a,b,c){return c&&c.length?(c.splice||(c=Array.prototype.slice.call(c)),c.splice(0,0,b),p["dynCall_"+a].apply(k,c)):p["dynCall_"+a].call(k,b)},eb:[],Vc:function(a){for(var b=0;b=F&&A("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+F+", (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.");return b},ub:function(a,b){return Math.ceil(a/(b?b:16))*(b?b:16)},Fg:function(a,b,c){return c?+(a>>>0)+4294967296*+(b>>>0):+(a>>>0)+4294967296* ++(b|0)},Pc:8,ia:4,Rf:0};p.Runtime=z;z.addFunction=z.Vc;z.removeFunction=z.Sd;var H=m,la,ma,ja;function w(a,b){a||A("Assertion failed: "+b)}function na(a){var b=p["_"+a];if(!b)try{b=eval("_"+a)}catch(c){}w(b,"Cannot call unknown function "+a+" (perhaps LLVM optimizations or closure removed it?)");return b}var oa,pa; +(function(){function a(a){a=a.toString().match(e).slice(1);return{arguments:a[0],body:a[1],returnValue:a[2]}}var b={stackSave:function(){z.Tb()},stackRestore:function(){z.Sb()},arrayToC:function(a){var b=z.pb(a.length);qa(a,b);return b},stringToC:function(a){var b=0;a!==k&&(a!==g&&0!==a)&&(b=z.pb((a.length<<2)+1),ra(a,b));return b}},c={string:b.stringToC,array:b.arrayToC};pa=function(a,b,e,f){var h=na(a),s=[],a=0;if(f)for(var v=0;v>0]=b;break;case "i8":I[a>>0]=b;break;case "i16":J[a>>1]=b;break;case "i32":K[a>>2]=b;break;case "i64":ma=[b>>>0,(la=b,1<=+ta(la)?0>>0:~~+xa((la-+(~~la>>>0))/4294967296)>>>0:0)];K[a>>2]=ma[0];K[a+4>>2]=ma[1];break;case "float":ya[a>>2]=b;break;case "double":za[a>>3]=b;break;default:A("invalid type for setValue: "+c)}}p.setValue=sa; +function Aa(a,b){b=b||"i8";"*"===b.charAt(b.length-1)&&(b="i32");switch(b){case "i1":return I[a>>0];case "i8":return I[a>>0];case "i16":return J[a>>1];case "i32":return K[a>>2];case "i64":return K[a>>2];case "float":return ya[a>>2];case "double":return za[a>>3];default:A("invalid type for setValue: "+b)}return k}p.getValue=Aa;var L=2,Ba=4;p.ALLOC_NORMAL=0;p.ALLOC_STACK=1;p.ALLOC_STATIC=L;p.ALLOC_DYNAMIC=3;p.ALLOC_NONE=Ba; +function M(a,b,c,e){var f,h;"number"===typeof a?(f=i,h=a):(f=m,h=a.length);var j="string"===typeof b?b:k,c=c==Ba?e:[Ca,z.pb,z.Ec,z.bb][c===g?L:c](Math.max(h,j?1:b.length));if(f){e=c;w(0==(c&3));for(a=c+(h&-4);e>2]=0;for(a=c+h;e>0]=0;return c}if("i8"===j)return a.subarray||a.slice?N.set(a,c):N.set(new Uint8Array(a),c),c;for(var e=0,l,u;e>0];if(128<=e)c=i;else if(0==e&&!b)break;f++;if(b&&f==b)break}b||(b=f);var h="";if(!c){for(;0>0],h+=c.nb(e);return h}p.Pointer_stringify=ka;p.UTF16ToString=function(a){for(var b=0,c="";;){var e=J[a+2*b>>1];if(0==e)return c;++b;c+=String.fromCharCode(e)}}; +p.stringToUTF16=function(a,b){for(var c=0;c>1]=a.charCodeAt(c);J[b+2*a.length>>1]=0};p.UTF32ToString=function(a){for(var b=0,c="";;){var e=K[a+4*b>>2];if(0==e)return c;++b;65536<=e?(e-=65536,c+=String.fromCharCode(55296|e>>10,56320|e&1023)):c+=String.fromCharCode(e)}};p.stringToUTF32=function(a,b){for(var c=0,e=0;e=f)var h=a.charCodeAt(++e),f=65536+((f&1023)<<10)|h&1023;K[b+4*c>>2]=f;++c}K[b+4*c>>2]=0}; +function Da(a){function b(c,e,f){var e=e||Infinity,h="",j=[],s;if("N"===a[l]){l++;"K"===a[l]&&l++;for(s=[];"E"!==a[l];)if("S"===a[l]){l++;var C=a.indexOf("_",l);s.push(q[a.substring(l,C)||0]||"?");l=C+1}else if("C"===a[l])s.push(s[s.length-1]),l+=2;else{var C=parseInt(a.substr(l)),P=C.toString().length;if(!C||!P){l--;break}var sb=a.substr(l+P,C);s.push(sb);q.push(sb);l+=P+C}l++;s=s.join("::");e--;if(0===e)return c?[s]:s}else if(("K"===a[l]||x&&"L"===a[l])&&l++,C=parseInt(a.substr(l)))P=C.toString().length, +s=a.substr(l+P,C),l+=P+C;x=m;"I"===a[l]?(l++,C=b(i),P=b(i,1,i),h+=P[0]+" "+s+"<"+C.join(", ")+">"):h=s;a:for(;lO?2*O:O+16777216; +O!==F&&(p.fa("increasing TOTAL_MEMORY to "+O+" to be compliant with the asm.js spec"),F=O);w("undefined"!==typeof Int32Array&&"undefined"!==typeof Float64Array&&!!(new Int32Array(1)).subarray&&!!(new Int32Array(1)).set,"JS engine does not provide full typed array support");var Q=new ArrayBuffer(F);I=new Int8Array(Q);J=new Int16Array(Q);K=new Int32Array(Q);N=new Uint8Array(Q);Ga=new Uint16Array(Q);Ha=new Uint32Array(Q);ya=new Float32Array(Q);za=new Float64Array(Q);K[0]=255;w(255===N[0]&&0===N[3],"Typed arrays 2 must be run on a little-endian system"); +p.HEAP=g;p.buffer=Q;p.HEAP8=I;p.HEAP16=J;p.HEAP32=K;p.HEAPU8=N;p.HEAPU16=Ga;p.HEAPU32=Ha;p.HEAPF32=ya;p.HEAPF64=za;function Na(a){for(;0>0]=a[c],c+=1}p.writeStringToMemory=ra;function qa(a,b){for(var c=0;c>0]=a[c]}p.writeArrayToMemory=qa; +p.writeAsciiToMemory=function(a,b,c){for(var e=0;e>0]=a.charCodeAt(e);c||(I[b+a.length>>0]=0)};if(!Math.imul||-5!==Math.imul(4294967295,5))Math.imul=function(a,b){var c=a&65535,e=b&65535;return c*e+((a>>>16)*e+c*(b>>>16)<<16)|0};Math.vg=Math.imul;var ta=Math.abs,xa=Math.ceil,wa=Math.floor,va=Math.min,S=0,Wa=k,Xa=k;function Ya(){S++;p.monitorRunDependencies&&p.monitorRunDependencies(S)}p.addRunDependency=Ya; +function Za(){S--;p.monitorRunDependencies&&p.monitorRunDependencies(S);if(0==S&&(Wa!==k&&(clearInterval(Wa),Wa=k),Xa)){var a=Xa;Xa=k;a()}}p.removeRunDependency=Za;p.preloadedImages={};p.preloadedAudios={};var T=k,Ia=8,D=Ia+7808;R.push(); +M([0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,0,0,0,0,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,0,0,0,0,10,0,0,0,13,0,0,0,16,0,0,0,11,0,0,0,14,0,0,0,18,0,0,0,13,0,0,0,16,0,0,0,20,0,0,0,14,0,0,0,18,0,0,0,23,0,0,0,16,0,0,0,20,0,0,0,25,0,0,0,18,0,0,0,23,0,0,0,29,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0, +0,0,14,0,0,0,15,0,0,0,16,0,0,0,17,0,0,0,18,0,0,0,19,0,0,0,20,0,0,0,21,0,0,0,22,0,0,0,23,0,0,0,24,0,0,0,25,0,0,0,26,0,0,0,27,0,0,0,28,0,0,0,29,0,0,0,29,0,0,0,30,0,0,0,31,0,0,0,32,0,0,0,32,0,0,0,33,0,0,0,34,0,0,0,34,0,0,0,35,0,0,0,35,0,0,0,36,0,0,0,36,0,0,0,37,0,0,0,37,0,0,0,37,0,0,0,38,0,0,0,38,0,0,0,38,0,0,0,39,0,0,0,39,0,0,0,39,0,0,0,39,0,0,0,1,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,16,0,0,0,32,0,0,0,64,0,0,0,128,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,1,0,0,0,4,0,0, +0,5,0,0,0,2,0,0,0,3,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,12,0,0,0,13,0,0,0,10,0,0,0,11,0,0,0,14,0,0,0,15,0,0,0,47,31,15,0,23,27,29,30,7,11,13,14,39,43,45,46,16,3,5,10,12,19,21,26,28,35,37,42,44,1,2,4,8,17,18,20,24,6,9,22,25,32,33,34,36,40,38,41,0,16,1,2,4,8,32,3,5,10,12,15,47,7,11,13,14,6,9,31,35,37,42,44,33,34,36,40,39,43,45,46,17,18,20,24,19,21,26,28,23,27,29,30,22,25,38,41,17,1,0,0,0,0,0,0,34,18,1,1,0,0,0,0,50,34,18,2,0,0,0,0,67,51,34,34,18,18,2,2,83,67,51,35,18,18,2,2,19,35,67,51,99,83,2,2,0, +0,101,85,68,68,52,52,35,35,35,35,19,19,19,19,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,249,233,217,200,200,184,184,167,167,167,167,151,151,151,151,134,134,134,134,134,134,134,134,118,118,118,118,118,118,118,118,230,214,198,182,165,165,149,149,132,132,132,132,116,116,116,116,100,100,100,100,84,84,84,84,67,67,67,67,67,67,67,67,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,19,19,19,19,19,19,19,19,3,3,3,3,3,3,3,3,214,182,197,197,165,165,149,149,132,132,132,132,84,84,84,84,68,68,68,68,4,4,4,4,115,115,115,115, +115,115,115,115,99,99,99,99,99,99,99,99,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,19,19,19,19,19,19,19,19,197,181,165,5,148,148,116,116,52,52,36,36,131,131,131,131,99,99,99,99,83,83,83,83,67,67,67,67,19,19,19,19,181,149,164,164,132,132,36,36,20,20,4,4,115,115,115,115,99,99,99,99,83,83,83,83,67,67,67,67,51,51,51,51,166,6,21,21,132,132,132,132,147,147,147,147,147,147,147,147,115,115,115,115,115,115,115,115,99,99,99,99,99,99,99,99,83,83,83,83,83,83,83,83,67,67,67,67,67,67,67,67,51,51,51,51,51, +51,51,51,35,35,35,35,35,35,35,35,150,6,21,21,116,116,116,116,131,131,131,131,131,131,131,131,99,99,99,99,99,99,99,99,67,67,67,67,67,67,67,67,51,51,51,51,51,51,51,51,35,35,35,35,35,35,35,35,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,134,6,37,37,20,20,20,20,115,115,115,115,115,115,115,115,99,99,99,99,99,99,99,99,51,51,51,51,51,51,51,51,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,22,6,117,117,36,36,36,36,83,83,83,83,83,83,83,83,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,21,5,100,100,35,35,35,35,82,82,82,82,82,82,82,82,66,66,66,66,66,66,66,66,50,50,50,50,50,50,50,50,4,20,35,35,51,51,83,83,65,65,65,65,65,65,65,65,4,20,67,67,34,34,34,34,49,49,49,49,49,49,49,49,3,19,50,50,33,33,33,33,2,18,33,33,0,0,0,0,0,0,0,0,0,0,102,32,38,16,6,8,101,24,101,24,67,16,67,16,67,16,67,16,67,16,67,16,67,16,67,16,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34,8,34, +8,34,8,34,8,34,8,34,8,34,8,34,8,0,0,0,0,0,0,0,0,106,64,74,48,42,40,10,32,105,56,105,56,73,40,73,40,41,32,41,32,9,24,9,24,104,48,104,48,104,48,104,48,72,32,72,32,72,32,72,32,40,24,40,24,40,24,40,24,8,16,8,16,8,16,8,16,103,40,103,40,103,40,103,40,103,40,103,40,103,40,103,40,71,24,71,24,71,24,71,24,71,24,71,24,71,24,71,24,110,96,78,88,46,80,14,80,110,88,78,80,46,72,14,72,13,64,13,64,77,72,77,72,45,64,45,64,13,56,13,56,109,80,109,80,77,64,77,64,45,56,45,56,13,48,13,48,107,72,107,72,107,72,107,72,107, +72,107,72,107,72,107,72,75,56,75,56,75,56,75,56,75,56,75,56,75,56,75,56,43,48,43,48,43,48,43,48,43,48,43,48,43,48,43,48,11,40,11,40,11,40,11,40,11,40,11,40,11,40,11,40,0,0,0,0,47,104,47,104,16,128,80,128,48,128,16,120,112,128,80,120,48,120,16,112,112,120,80,112,48,112,16,104,111,112,111,112,79,104,79,104,47,96,47,96,15,96,15,96,111,104,111,104,79,96,79,96,47,88,47,88,15,88,15,88,0,0,0,0,0,0,0,0,102,56,70,32,38,32,6,16,102,48,70,24,38,24,6,8,101,40,101,40,37,16,37,16,100,32,100,32,100,32,100,32,100, +24,100,24,100,24,100,24,67,16,67,16,67,16,67,16,67,16,67,16,67,16,67,16,0,0,0,0,0,0,0,0,105,72,73,56,41,56,9,48,8,40,8,40,72,48,72,48,40,48,40,48,8,32,8,32,103,64,103,64,103,64,103,64,71,40,71,40,71,40,71,40,39,40,39,40,39,40,39,40,7,24,7,24,7,24,7,24,0,0,0,0,109,120,109,120,110,128,78,128,46,128,14,128,46,120,14,120,78,120,46,112,77,112,77,112,13,112,13,112,109,112,109,112,77,104,77,104,45,104,45,104,13,104,13,104,109,104,109,104,77,96,77,96,45,96,45,96,13,96,13,96,12,88,12,88,12,88,12,88,76,88, +76,88,76,88,76,88,44,88,44,88,44,88,44,88,12,80,12,80,12,80,12,80,108,96,108,96,108,96,108,96,76,80,76,80,76,80,76,80,44,80,44,80,44,80,44,80,12,72,12,72,12,72,12,72,107,88,107,88,107,88,107,88,107,88,107,88,107,88,107,88,75,72,75,72,75,72,75,72,75,72,75,72,75,72,75,72,43,72,43,72,43,72,43,72,43,72,43,72,43,72,43,72,11,64,11,64,11,64,11,64,11,64,11,64,11,64,11,64,107,80,107,80,107,80,107,80,107,80,107,80,107,80,107,80,75,64,75,64,75,64,75,64,75,64,75,64,75,64,75,64,43,64,43,64,43,64,43,64,43,64,43, +64,43,64,43,64,11,56,11,56,11,56,11,56,11,56,11,56,11,56,11,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,24,70,56,38,56,6,16,102,72,70,48,38,48,6,8,37,40,37,40,69,40,69,40,37,32,37,32,69,32,69,32,37,24,37,24,101,64,101,64,69,24,69,24,37,16,37,16,100,56,100,56,100,56,100,56,100,48,100,48,100,48,100,48,100,40,100,40,100,40,100,40,100,32,100,32,100,32,100,32,100,24,100,24,100,24,100,24,68,16,68,16,68,16,68,16,36,8,36,8,36,8,36,8,4,0,4,0,4,0,4,0,0,0,10,128,106,128,74,128,42,128,10,120,106,120,74,120,42,120,10, +112,106,112,74,112,42,112,10,104,41,104,41,104,9,96,9,96,73,104,73,104,41,96,41,96,9,88,9,88,105,104,105,104,73,96,73,96,41,88,41,88,9,80,9,80,104,96,104,96,104,96,104,96,72,88,72,88,72,88,72,88,40,80,40,80,40,80,40,80,8,72,8,72,8,72,8,72,104,88,104,88,104,88,104,88,72,80,72,80,72,80,72,80,40,72,40,72,40,72,40,72,8,64,8,64,8,64,8,64,7,56,7,56,7,56,7,56,7,56,7,56,7,56,7,56,7,48,7,48,7,48,7,48,7,48,7,48,7,48,7,48,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,7,40,7,40,7,40,7,40,7,40,7,40,7,40,7,40, +103,80,103,80,103,80,103,80,103,80,103,80,103,80,103,80,71,64,71,64,71,64,71,64,71,64,71,64,71,64,71,64,39,64,39,64,39,64,39,64,39,64,39,64,39,64,39,64,7,32,7,32,7,32,7,32,7,32,7,32,7,32,7,32,6,8,38,8,0,0,6,0,6,16,38,16,70,16,0,0,6,24,38,24,70,24,102,24,6,32,38,32,70,32,102,32,6,40,38,40,70,40,102,40,6,48,38,48,70,48,102,48,6,56,38,56,70,56,102,56,6,64,38,64,70,64,102,64,6,72,38,72,70,72,102,72,6,80,38,80,70,80,102,80,6,88,38,88,70,88,102,88,6,96,38,96,70,96,102,96,6,104,38,104,70,104,102,104,6,112, +38,112,70,112,102,112,6,120,38,120,70,120,102,120,6,128,38,128,70,128,102,128,0,0,67,16,2,0,2,0,33,8,33,8,33,8,33,8,103,32,103,32,72,32,40,32,71,24,71,24,39,24,39,24,6,32,6,32,6,32,6,32,6,24,6,24,6,24,6,24,6,16,6,16,6,16,6,16,102,24,102,24,102,24,102,24,38,16,38,16,38,16,38,16,6,8,6,8,6,8,6,8,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,3, +0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,3,0,0,0,19,0,0,0,1,0,0,0,18,0,0,0,0,0,0,0,17,0,0,0,4,0,0,0,16,0,0,0,3,0,0,0,23,0,0,0,1,0,0,0,22,0,0,0,0,0,0,0,21,0,0,0,4,0,0,0,20,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,4,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,12,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,4,0,0,0,13,0,0,0,255,0,0,0,8,0,0,0,1,0,0,0,19,0,0,0,2,0,0,0,18,0,0,0,4,0, +0,0,17,0,0,0,255,0,0,0,16,0,0,0,1,0,0,0,23,0,0,0,2,0,0,0,22,0,0,0,4,0,0,0,21,0,0,0,255,0,0,0,20,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,13,0,0,0,1,0,0,0,18,0,0,0,1,0,0,0,19,0,0,0,4,0,0,0,16,0,0,0,4,0,0,0,17,0,0,0,1,0,0,0,22,0,0,0,1,0,0,0,23,0,0,0,4,0,0,0,20,0,0,0,4,0,0,0,21,0,0,0,0, +0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,15,0,0,0,4,0,0,0,10,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,11,0,0,0,4,0,0,0,14,0,0,0,0,0,0,0,17,0,0,0,4,0,0,0,16,0,0,0,0,0,0,0,19,0,0,0,4,0,0,0,18,0,0,0,0,0,0,0,21,0,0,0,4,0,0,0,20,0,0,0,0,0,0,0,23,0,0,0,4,0,0,0,22,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0,12,0,0,0,8,0,0,0,12,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,8,0,0,0, +12,0,0,0,8,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,8,0,0,0,8,0,0,0,12,0,0,0,12,0,0,0,8,0,0,0,8,0,0,0,12,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108, +109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234, +235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,0,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,3,0,0,0,15,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,1,0,0,0,255,0, +0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,13,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0, +0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,4,0,0,0,2,0,0,0,10,0,0, +0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,2,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,15,0,0,0,2,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0, +0,0,4,0,0,0,9,0,0,0,255,0,0,0,12,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,2,0,0,0,4,0,0,0,13,0,0,0,255,0,0,0,8,0,0,0,1,0,0,0,10,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,4,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,255,0, +0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,11,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,14,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,4,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,1,0,0,0,15,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,4,0,0,0,2,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0, +0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,8,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,6,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,13,0,0,0,0,0,0,0,5,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0, +0,0,0,7,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,2,0,0,0,4,0,0,0,1,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,3,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,13,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0, +0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,15,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,0,0,0,8,0,0,0,0,0,0,0,15,0,0,0,4,0,0,0,10,0,0,0,4,0,0,0,9,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,11,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,4,0,0,0,9,0,0,0,4,0,0,0,12,0,0,0,4,0,0,0,11,0,0,0,4,0,0,0,14,0,0, +0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0,0,0,14,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,5,6,7,8,9,10,12,13,15,17,20,22,25,28,32,36,40,45,50,56,63,71,80,90,101,113,127,144,162,182,203,226,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,3,4,4,4,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,1,1,2,1,1,2,1,2,3,1,2,3,2,2,3,2,2,4,2,3,4,2,3,4,3,3,5,3,4,6,3,4,6,4,5,7,4,5,8,4,6,9,5,7,10,6,8,11,6,8,13,7,10,14,8,11,16,9,12,18,10,13,20,11,15,23,13,17,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,69,67,79,68,69,82,32,73,78,73,84,73,65,76,73,90,65,84,73,79,78,32,70,65,73,76,69,68,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"i8",Ba,z.Pc);var $a=z.ub(M(12,"i8",L),8);w(0==$a%8); +var U={O:1,Q:2,Ef:3,De:4,ha:5,Zb:6,be:7,$e:8,V:9,oe:10,Ca:11,Of:11,Mc:12,qb:13,ye:14,mf:15,ga:16,Xb:17,Oc:18,Qa:19,Sa:20,pa:21,B:22,Ve:23,Lc:24,Nc:25,Lf:26,ze:27,hf:28,Ua:29,Bf:30,Oe:31,uf:32,ve:33,yf:34,df:42,Be:43,pe:44,Fe:45,Ge:46,He:47,Ne:48,Mf:49,Ye:50,Ee:51,te:35,af:37,ge:52,je:53,Pf:54,We:55,ke:56,le:57,ue:35,me:59,kf:60,Ze:61,If:62,jf:63,ef:64,ff:65,Af:66,bf:67,ee:68,Ff:69,qe:70,vf:71,Qe:72,we:73,ie:74,qf:76,he:77,zf:78,Ie:79,Je:80,Me:81,Le:82,Ke:83,lf:38,sb:39,Re:36,rb:40,Ta:95,tf:96,se:104, +Xe:105,fe:97,xf:91,of:88,gf:92,Cf:108,Wb:111,ce:98,re:103,Ue:101,Se:100,Jf:110,Ae:112,Yb:113,Jc:115,Hc:114,Ic:89,Pe:90,wf:93,Df:94,de:99,Te:102,Kc:106,Ra:107,Kf:109,Nf:87,xe:122,Gf:116,pf:95,cf:123,Ce:84,rf:75,ne:125,nf:131,sf:130,Hf:86},ab={"0":"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes", +12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func", +34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange", +53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)", +74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required", +90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected", +107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"},bb=0;function V(a){return K[bb>>2]=a} +function cb(a,b){for(var c=0,e=a.length-1;0<=e;e--){var f=a[e];"."===f?a.splice(e,1):".."===f?(a.splice(e,1),c++):c&&(a.splice(e,1),c--)}if(b)for(;c--;c)a.unshift("..");return a}function db(a){var b="/"===a.charAt(0),c="/"===a.substr(-1),a=cb(a.split("/").filter(function(a){return!!a}),!b).join("/");!a&&!b&&(a=".");a&&c&&(a+="/");return(b?"/":"")+a} +function eb(a){var b=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(a).slice(1),a=b[0],b=b[1];if(!a&&!b)return".";b&&(b=b.substr(0,b.length-1));return a+b}function W(a){if("/"===a)return"/";var b=a.lastIndexOf("/");return-1===b?a:a.substr(b+1)}function fb(){var a=Array.prototype.slice.call(arguments,0);return db(a.join("/"))}function X(a,b){return db(a+"/"+b)} +function gb(){for(var a="",b=m,c=arguments.length-1;-1<=c&&!b;c--){b=0<=c?arguments[c]:B.yb();"string"!==typeof b&&d(new TypeError("Arguments to path.resolve must be strings"));if(!b)return"";a=b+"/"+a;b="/"===b.charAt(0)}a=cb(a.split("/").filter(function(a){return!!a}),!b).join("/");return(b?"/":"")+a||"."} +function hb(a,b){function c(a){for(var b=0;bc?[]:a.slice(b,c-b+1)}for(var a=gb(a).substr(1),b=gb(b).substr(1),e=c(a.split("/")),f=c(b.split("/")),h=Math.min(e.length,f.length),j=h,l=0;la.k.length)&&(a.k=Y.ud(a),a.q=a.k.length);if(!a.k||a.k.subarray){var c=a.k?a.k.buffer.byteLength:0;c>=b||(b=Math.max(b,c*(1048576>c?2:1.125)|0),0!=c&&(b=Math.max(b,256)),c=a.k,a.k=new Uint8Array(b),0b)a.k.length=b;else for(;a.k.length=a.g.q)return 0;a=Math.min(a.g.q-f,e);w(0<=a);if(8b&&d(new B.e(U.B));return b},Ea:function(a,b,c){Y.lc(a.g,b+c);a.g.q=Math.max(a.g.q,b+c)},Ja:function(a,b,c,e,f,h,j){B.isFile(a.g.mode)||d(new B.e(U.Qa));c=a.g.k;if(!(j&2)&&(c.buffer===b||c.buffer=== +b.buffer))a=m,e=c.byteOffset;else{if(0>>0)%B.T.length},tc:function(a){var b=B.Fb(a.parent.id,a.name);a.ma=B.T[b];B.T[b]=a},uc:function(a){var b=B.Fb(a.parent.id,a.name);if(B.T[b]===a)B.T[b]=a.ma;else for(b=B.T[b];b;){if(b.ma===a){b.ma=a.ma;break}b=b.ma}},aa:function(a,b){var c=B.Gd(a);c&&d(new B.e(c,a));for(c=B.T[B.Fb(a.id,b)];c;c=c.ma){var e=c.name;if(c.parent.id===a.id&&e===b)return c}return B.ra(a,b)},createNode:function(a,b,c,e){B.Va||(B.Va=function(a,b,c,e){a|| +(a=this);this.parent=a;this.F=a.F;this.Ka=k;this.id=B.Jd++;this.name=b;this.mode=c;this.n={};this.p={};this.ob=e},B.Va.prototype={},Object.defineProperties(B.Va.prototype,{M:{get:function(){return 365===(this.mode&365)},set:function(a){a?this.mode|=365:this.mode&=-366}},write:{get:function(){return 146===(this.mode&146)},set:function(a){a?this.mode|=146:this.mode&=-147}},Dd:{get:function(){return B.J(this.mode)}},Gb:{get:function(){return B.ib(this.mode)}}}));a=new B.Va(a,b,c,e);B.tc(a);return a}, +zb:function(a){B.uc(a)},jb:function(a){return a===a.parent},ka:function(a){return!!a.Ka},isFile:function(a){return 32768===(a&61440)},J:function(a){return 16384===(a&61440)},Ia:function(a){return 40960===(a&61440)},ib:function(a){return 8192===(a&61440)},Bd:function(a){return 24576===(a&61440)},Cd:function(a){return 4096===(a&61440)},Ed:function(a){return 49152===(a&49152)},rd:{r:0,rs:1052672,"r+":2,w:577,wx:705,xw:705,"w+":578,"wx+":706,"xw+":706,a:1089,ax:1217,xa:1217,"a+":1090,"ax+":1218,"xa+":1218}, +wc:function(a){var b=B.rd[a];"undefined"===typeof b&&d(Error("Unknown file open mode: "+a));return b},sd:function(a){var b=["r","w","rw"][a&2097155];a&512&&(b+="w");return b},na:function(a,b){return B.vc?0:-1!==b.indexOf("r")&&!(a.mode&292)||-1!==b.indexOf("w")&&!(a.mode&146)||-1!==b.indexOf("x")&&!(a.mode&73)?U.qb:0},Gd:function(a){var b=B.na(a,"x");return b?b:!a.n.ra?U.qb:0},Jb:function(a,b){try{return B.aa(a,b),U.Xb}catch(c){}return B.na(a,"wx")},kb:function(a,b,c){var e;try{e=B.aa(a,b)}catch(f){return f.cb}if(a= +B.na(a,"wx"))return a;if(c){if(!B.J(e.mode))return U.Sa;if(B.jb(e)||B.da(e)===B.yb())return U.ga}else if(B.J(e.mode))return U.pa;return 0},Hd:function(a,b){return!a?U.Q:B.Ia(a.mode)?U.rb:B.J(a.mode)&&(0!==(b&2097155)||b&512)?U.pa:B.na(a,B.sd(b))},Qc:4096,Kd:function(a,b){for(var b=b||B.Qc,c=a||0;c<=b;c++)if(!B.oa[c])return c;d(new B.e(U.Lc))},qa:function(a){return B.oa[a]},fc:function(a,b,c){B.Wa||(B.Wa=n(),B.Wa.prototype={},Object.defineProperties(B.Wa.prototype,{object:{get:function(){return this.g}, +set:function(a){this.g=a}},yg:{get:function(){return 1!==(this.D&2097155)}},zg:{get:function(){return 0!==(this.D&2097155)}},xg:{get:function(){return this.D&1024}}}));var e=new B.Wa,f;for(f in a)e[f]=a[f];a=e;b=B.Kd(b,c);a.C=b;return B.oa[b]=a},dd:function(a){B.oa[a]=k},pc:function(a){return B.oa[a-1]},Eb:function(a){return a?a.C+1:0},bd:{open:function(a){a.p=B.td(a.g.ob).p;a.p.open&&a.p.open(a)},$:function(){d(new B.e(U.Ua))}},Ib:function(a){return a>>8},Gg:function(a){return a&255},la:function(a, +b){return a<<8|b},Ob:function(a,b){B.ic[a]={p:b}},td:function(a){return B.ic[a]},nc:function(a){for(var b=[],a=[a];a.length;){var c=a.pop();b.push(c);a.push.apply(a,c.La)}return b},Fc:function(a,b){function c(a){if(a){if(!c.pd)return c.pd=i,b(a)}else++f>=e.length&&b(k)}"function"===typeof a&&(b=a,a=m);var e=B.nc(B.root.F),f=0;e.forEach(function(b){if(!b.type.Fc)return c(k);b.type.Fc(b,a,c)})},F:function(a,b,c){var e="/"===c,f=!c,h;e&&B.root&&d(new B.e(U.ga));!e&&!f&&(h=B.u(c,{Bb:m}),c=h.path,h=h.g, +B.ka(h)&&d(new B.e(U.ga)),B.J(h.mode)||d(new B.e(U.Sa)));b={type:a,Kg:b,Id:c,La:[]};a=a.F(b);a.F=b;b.root=a;e?B.root=a:h&&(h.Ka=b,h.F&&h.F.La.push(b));return a},Qg:function(a){a=B.u(a,{Bb:m});B.ka(a.g)||d(new B.e(U.B));var a=a.g,b=a.Ka,c=B.nc(b);Object.keys(B.T).forEach(function(a){for(a=B.T[a];a;){var b=a.ma;-1!==c.indexOf(a.F)&&B.zb(a);a=b}});a.Ka=k;b=a.F.La.indexOf(b);w(-1!==b);a.F.La.splice(b,1)},ra:function(a,b){return a.n.ra(a,b)},ba:function(a,b,c){var e=B.u(a,{parent:i}).g,a=W(a);(!a||"."=== +a||".."===a)&&d(new B.e(U.B));var f=B.Jb(e,a);f&&d(new B.e(f));e.n.ba||d(new B.e(U.O));return e.n.ba(e,a,b,c)},create:function(a,b){b=(b!==g?b:438)&4095;b|=32768;return B.ba(a,b,0)},ea:function(a,b){b=(b!==g?b:511)&1023;b|=16384;return B.ba(a,b,0)},lb:function(a,b,c){"undefined"===typeof c&&(c=b,b=438);return B.ba(a,b|8192,c)},ca:function(a,b){gb(a)||d(new B.e(U.Q));var c=B.u(b,{parent:i}).g;c||d(new B.e(U.Q));var e=W(b),f=B.Jb(c,e);f&&d(new B.e(f));c.n.ca||d(new B.e(U.O));return c.n.ca(c,e,a)},rename:function(a, +b){var c=eb(a),e=eb(b),f=W(a),h=W(b),j,l,u;try{j=B.u(a,{parent:i}),l=j.g,j=B.u(b,{parent:i}),u=j.g}catch(q){d(new B.e(U.ga))}(!l||!u)&&d(new B.e(U.Q));l.F!==u.F&&d(new B.e(U.Oc));j=B.aa(l,f);e=hb(a,e);"."!==e.charAt(0)&&d(new B.e(U.B));e=hb(b,c);"."!==e.charAt(0)&&d(new B.e(U.sb));var x;try{x=B.aa(u,h)}catch(s){}if(j!==x){c=B.J(j.mode);(f=B.kb(l,f,c))&&d(new B.e(f));(f=x?B.kb(u,h,c):B.Jb(u,h))&&d(new B.e(f));l.n.rename||d(new B.e(U.O));(B.ka(j)||x&&B.ka(x))&&d(new B.e(U.ga));u!==l&&(f=B.na(l,"w"))&& +d(new B.e(f));try{B.H.willMovePath&&B.H.willMovePath(a,b)}catch(v){console.log("FS.trackingDelegate['willMovePath']('"+a+"', '"+b+"') threw an exception: "+v.message)}B.uc(j);try{l.n.rename(j,u,h)}catch(G){d(G)}finally{B.tc(j)}try{if(B.H.onMovePath)B.H.onMovePath(a,b)}catch(ua){console.log("FS.trackingDelegate['onMovePath']('"+a+"', '"+b+"') threw an exception: "+ua.message)}}},Oa:function(a){var b=B.u(a,{parent:i}).g,c=W(a),e=B.aa(b,c),f=B.kb(b,c,i);f&&d(new B.e(f));b.n.Oa||d(new B.e(U.O));B.ka(e)&& +d(new B.e(U.ga));try{B.H.willDeletePath&&B.H.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.n.Oa(b,c);B.zb(e);try{if(B.H.onDeletePath)B.H.onDeletePath(a)}catch(j){console.log("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+j.message)}},Na:function(a){a=B.u(a,{R:i}).g;a.n.Na||d(new B.e(U.Sa));return a.n.Na(a)},za:function(a){var b=B.u(a,{parent:i}).g,c=W(a),e=B.aa(b,c),f=B.kb(b,c,m);f&&(f===U.pa&&(f=U.O), +d(new B.e(f)));b.n.za||d(new B.e(U.O));B.ka(e)&&d(new B.e(U.ga));try{B.H.willDeletePath&&B.H.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.n.za(b,c);B.zb(e);try{if(B.H.onDeletePath)B.H.onDeletePath(a)}catch(j){console.log("FS.trackingDelegate['onDeletePath']('"+a+"') threw an exception: "+j.message)}},ta:function(a){(a=B.u(a).g)||d(new B.e(U.Q));a.n.ta||d(new B.e(U.B));return a.n.ta(a)},Dc:function(a,b){var c=B.u(a,{R:!b}).g; +c||d(new B.e(U.Q));c.n.S||d(new B.e(U.O));return c.n.S(c)},Eg:function(a){return B.Dc(a,i)},Ya:function(a,b,c){a="string"===typeof a?B.u(a,{R:!c}).g:a;a.n.I||d(new B.e(U.O));a.n.I(a,{mode:b&4095|a.mode&-4096,timestamp:Date.now()})},Bg:function(a,b){B.Ya(a,b,i)},jg:function(a,b){var c=B.qa(a);c||d(new B.e(U.V));B.Ya(c.g,b)},dc:function(a,b,c,e){a="string"===typeof a?B.u(a,{R:!e}).g:a;a.n.I||d(new B.e(U.O));a.n.I(a,{timestamp:Date.now()})},Cg:function(a,b,c){B.dc(a,b,c,i)},kg:function(a,b,c){(a=B.qa(a))|| +d(new B.e(U.V));B.dc(a.g,b,c)},truncate:function(a,b){0>b&&d(new B.e(U.B));var c;c="string"===typeof a?B.u(a,{R:i}).g:a;c.n.I||d(new B.e(U.O));B.J(c.mode)&&d(new B.e(U.pa));B.isFile(c.mode)||d(new B.e(U.B));var e=B.na(c,"w");e&&d(new B.e(e));c.n.I(c,{size:b,timestamp:Date.now()})},mg:function(a,b){var c=B.qa(a);c||d(new B.e(U.V));0===(c.D&2097155)&&d(new B.e(U.B));B.truncate(c.g,b)},Rg:function(a,b,c){a=B.u(a,{R:i}).g;a.n.I(a,{timestamp:Math.max(b,c)})},open:function(a,b,c,e,f){""===a&&d(new B.e(U.Q)); +var b="string"===typeof b?B.wc(b):b,c=b&64?("undefined"===typeof c?438:c)&4095|32768:0,h;if("object"===typeof a)h=a;else{a=db(a);try{h=B.u(a,{R:!(b&131072)}).g}catch(j){}}var l=m;b&64&&(h?b&128&&d(new B.e(U.Xb)):(h=B.ba(a,c,0),l=i));h||d(new B.e(U.Q));B.ib(h.mode)&&(b&=-513);l||(c=B.Hd(h,b))&&d(new B.e(c));b&512&&B.truncate(h,0);b&=-641;e=B.fc({g:h,path:B.da(h),D:b,seekable:i,position:0,p:h.p,$d:[],error:m},e,f);e.p.open&&e.p.open(e);p.logReadFiles&&!(b&1)&&(B.Mb||(B.Mb={}),a in B.Mb||(B.Mb[a]=1, +p.printErr("read file: "+a)));try{B.H.onOpenFile&&(f=0,1!==(b&2097155)&&(f|=B.Gc.yc.Rc),0!==(b&2097155)&&(f|=B.Gc.yc.Sc),B.H.onOpenFile(a,f))}catch(u){console.log("FS.trackingDelegate['onOpenFile']('"+a+"', flags) threw an exception: "+u.message)}return e},close:function(a){try{a.p.close&&a.p.close(a)}catch(b){d(b)}finally{B.dd(a.C)}},$:function(a,b,c){(!a.seekable||!a.p.$)&&d(new B.e(U.Ua));a.position=a.p.$(a,b,c);a.$d=[];return a.position},M:function(a,b,c,e,f){(0>e||0>f)&&d(new B.e(U.B));1===(a.D& +2097155)&&d(new B.e(U.V));B.J(a.g.mode)&&d(new B.e(U.pa));a.p.M||d(new B.e(U.B));var h=i;"undefined"===typeof f?(f=a.position,h=m):a.seekable||d(new B.e(U.Ua));b=a.p.M(a,b,c,e,f);h||(a.position+=b);return b},write:function(a,b,c,e,f,h){(0>e||0>f)&&d(new B.e(U.B));0===(a.D&2097155)&&d(new B.e(U.V));B.J(a.g.mode)&&d(new B.e(U.pa));a.p.write||d(new B.e(U.B));a.D&1024&&B.$(a,0,2);var j=i;"undefined"===typeof f?(f=a.position,j=m):a.seekable||d(new B.e(U.Ua));b=a.p.write(a,b,c,e,f,h);j||(a.position+=b); +try{if(a.path&&B.H.onWriteToFile)B.H.onWriteToFile(a.path)}catch(l){console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: "+l.message)}return b},Ea:function(a,b,c){(0>b||0>=c)&&d(new B.e(U.B));0===(a.D&2097155)&&d(new B.e(U.V));!B.isFile(a.g.mode)&&!B.J(node.mode)&&d(new B.e(U.Qa));a.p.Ea||d(new B.e(U.Ta));a.p.Ea(a,b,c)},Ja:function(a,b,c,e,f,h,j){1===(a.D&2097155)&&d(new B.e(U.qb));a.p.Ja||d(new B.e(U.Qa));return a.p.Ja(a,b,c,e,f,h,j)},Ha:function(a,b,c){a.p.Ha||d(new B.e(U.Nc)); +return a.p.Ha(a,b,c)},Mg:function(a,b){b=b||{};b.D=b.D||"r";b.encoding=b.encoding||"binary";"utf8"!==b.encoding&&"binary"!==b.encoding&&d(Error('Invalid encoding type "'+b.encoding+'"'));var c,e=B.open(a,b.D),f=B.Dc(a).size,h=new Uint8Array(f);B.M(e,h,0,f,0);if("utf8"===b.encoding){c="";for(var j=new z.Da,l=0;l>2]=B.Eb(a);w(0===a.C,"invalid handle for stdin ("+a.C+")");a=B.open("/dev/stdout","w");K[pb>>2]=B.Eb(a);w(1===a.C,"invalid handle for stdout ("+a.C+")");a=B.open("/dev/stderr","w");K[qb>>2]=B.Eb(a);w(2===a.C,"invalid handle for stderr ("+a.C+")")},jc:function(){B.e||(B.e=function(a,b){this.g=b;this.Xd=function(a){this.cb=a;for(var b in U)if(U[b]=== +a){this.code=b;break}};this.Xd(a);this.message=ab[a]},B.e.prototype=Error(),[U.Q].forEach(function(a){B.Db[a]=new B.e(a);B.Db[a].stack=""}))},Zd:function(){B.jc();B.T=Array(4096);B.F(Y,{},"/");B.fd();B.ed()},Ga:function(a,b,c){w(!B.Ga.hb,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");B.Ga.hb=i;B.jc();p.stdin=a||p.stdin;p.stdout=b||p.stdout;p.stderr= +c||p.stderr;B.od()},Qd:function(){B.Ga.hb=m;for(var a=0;athis.length-1||0>a)){var b=a%this.cd;return this.yd(a/ +this.cd|0)[b]}};h.prototype.Wd=function(a){this.yd=a};h.prototype.bc=function(){var a=new XMLHttpRequest;a.open("HEAD",c,m);a.send(k);200<=a.status&&300>a.status||304===a.status||d(Error("Couldn't load "+c+". Status: "+a.status));var b=Number(a.getResponseHeader("Content-length")),e,f=1048576;if(!((e=a.getResponseHeader("Accept-Ranges"))&&"bytes"===e))f=b;var h=this;h.Wd(function(a){var e=a*f,j=(a+1)*f-1,j=Math.min(j,b-1);if("undefined"===typeof h.Za[a]){var l=h.Za;e>j&&d(Error("invalid range ("+ +e+", "+j+") or no bytes requested!"));j>b-1&&d(Error("only "+b+" bytes available! programmer error!"));var q=new XMLHttpRequest;q.open("GET",c,m);b!==f&&q.setRequestHeader("Range","bytes="+e+"-"+j);"undefined"!=typeof Uint8Array&&(q.responseType="arraybuffer");q.overrideMimeType&&q.overrideMimeType("text/plain; charset=x-user-defined");q.send(k);200<=q.status&&300>q.status||304===q.status||d(Error("Couldn't load "+c+". Status: "+q.status));e=q.response!==g?new Uint8Array(q.response||[]):Va(q.responseText|| +"",i);l[a]=e}"undefined"===typeof h.Za[a]&&d(Error("doXHR failed!"));return h.Za[a]});this.Uc=b;this.Tc=f;this.Hb=i};if("undefined"!==typeof XMLHttpRequest){ca||d("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc");var j=new h;Object.defineProperty(j,"length",{get:function(){this.Hb||this.bc();return this.Uc}});Object.defineProperty(j,"chunkSize",{get:function(){this.Hb||this.bc();return this.Tc}});j={Gb:m,k:j}}else j={Gb:m,url:c}; +var l=B.gd(a,b,j,e,f);j.k?l.k=j.k:j.url&&(l.k=k,l.url=j.url);Object.defineProperty(l,"usedBytes",{get:function(){return this.k.length}});var u={};Object.keys(l.p).forEach(function(a){var b=l.p[a];u[a]=function(){B.mc(l)||d(new B.e(U.ha));return b.apply(k,arguments)}});u.M=function(a,b,c,e,f){B.mc(l)||d(new B.e(U.ha));a=a.g.k;if(f>=a.length)return 0;e=Math.min(a.length-f,e);w(0<=e);if(a.slice)for(var h=0;h>h-6&63,h=h-6,c=c+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[q]}2==h?(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&3)<<4],c+="=="):4==h&&(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&15)<<2],c+="="); +s.src="data:audio/x-"+b.substr(-3)+";base64,"+c;f(s)}};s.src=l;p.noExitRuntime=i;setTimeout(function(){H||f(s)},1E4)}else return h()}});var v=p.canvas;v&&(v.Pb=v.requestPointerLock||v.mozRequestPointerLock||v.webkitRequestPointerLock||v.msRequestPointerLock||n(),v.kc=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock||document.msExitPointerLock||n(),v.kc=v.kc.bind(document),document.addEventListener("pointerlockchange",q,m),document.addEventListener("mozpointerlockchange", +q,m),document.addEventListener("webkitpointerlockchange",q,m),document.addEventListener("mspointerlockchange",q,m),p.elementPointerLock&&v.addEventListener("click",function(a){!rb&&v.Pb&&(v.Pb(),a.preventDefault())},m))}var G=b?gb(X(a,b)):a;Ya();"string"==typeof c?yb(c,function(a){x(a)},j):x(c)},indexedDB:function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},Ub:function(){return"EM_FS_"+window.location.pathname},Vb:20,Ba:"FILE_DATA",Og:function(a,b,c){var b= +b||n(),c=c||n(),e=B.indexedDB();try{var f=e.open(B.Ub(),B.Vb)}catch(h){return c(h)}f.Ld=function(){console.log("creating db");f.result.createObjectStore(B.Ba)};f.onsuccess=function(){var e=f.result.transaction([B.Ba],"readwrite"),h=e.objectStore(B.Ba),u=0,q=0,x=a.length;a.forEach(function(a){a=h.put(B.vb(a).object.k,a);a.onsuccess=function(){u++;u+q==x&&(0==q?b():c())};a.onerror=function(){q++;u+q==x&&(0==q?b():c())}});e.onerror=c};f.onerror=c},Dg:function(a,b,c){var b=b||n(),c=c||n(),e=B.indexedDB(); +try{var f=e.open(B.Ub(),B.Vb)}catch(h){return c(h)}f.Ld=c;f.onsuccess=function(){var e=f.result;try{var h=e.transaction([B.Ba],"readonly")}catch(u){c(u);return}var q=h.objectStore(B.Ba),x=0,s=0,v=a.length;a.forEach(function(a){var e=q.get(a);e.onsuccess=function(){B.vb(a).Ab&&B.za(a);B.xb(eb(a),W(a),e.result,i,i,i);x++;x+s==v&&(0==s?b():c())};e.onerror=function(){s++;x+s==v&&(0==s?b():c())}});h.onerror=c};f.onerror=c}};function zb(){d("TODO")} +var Z={F:function(){p.websocket=p.websocket&&"object"===typeof p.websocket?p.websocket:{};p.websocket.tb={};p.websocket.on=function(a,b){"function"===typeof b&&(this.tb[a]=b);return this};p.websocket.P=function(a,b){"function"===typeof this.tb[a]&&this.tb[a].call(this,b)};return B.createNode(k,"/",16895,0)},nd:function(a,b,c){c&&w(1==b==(6==c));a={qd:a,type:b,protocol:c,G:k,error:k,Ma:{},Kb:[],ua:[],wa:Z.L};b=Z.mb();c=B.createNode(Z.root,b,49152,0);c.va=a;b=B.fc({path:b,g:c,D:B.wc("r+"),seekable:m, +p:Z.p});a.A=b;return a},wd:function(a){a=B.qa(a);return!a||!B.Ed(a.g.mode)?k:a.g.va},p:{zc:function(a){a=a.g.va;return a.wa.zc(a)},Ha:function(a,b,c){a=a.g.va;return a.wa.Ha(a,b,c)},M:function(a,b,c,e){a=a.g.va;e=a.wa.Rd(a,e);if(!e)return 0;b.set(e.buffer,c);return e.buffer.length},write:function(a,b,c,e){a=a.g.va;return a.wa.Vd(a,b,c,e)},close:function(a){a=a.g.va;a.wa.close(a)}},mb:function(){Z.mb.gc||(Z.mb.gc=0);return"socket["+Z.mb.gc++ +"]"},L:{$a:function(a,b,c){var e;"object"===typeof b&&(e= +b,c=b=k);if(e)e._socket?(b=e._socket.remoteAddress,c=e._socket.remotePort):((c=/ws[s]?:\/\/([^:]+):(\d+)/.exec(e.url))||d(Error("WebSocket URL must be in the format ws(s)://address:port")),b=c[1],c=parseInt(c[2],10));else try{var f=p.websocket&&"object"===typeof p.websocket,h="ws:#".replace("#","//");f&&"string"===typeof p.websocket.url&&(h=p.websocket.url);if("ws://"===h||"wss://"===h)var j=b.split("/"),h=h+j[0]+":"+c+"/"+j.slice(1).join("/");j="binary";f&&"string"===typeof p.websocket.subprotocol&& +(j=p.websocket.subprotocol);var j=j.replace(/^ +| +$/g,"").split(/ *, */),l=t?{protocol:j.toString()}:j;e=new (t?(null)("ws"):window.WebSocket)(h,l);e.binaryType="arraybuffer"}catch(u){d(new B.e(U.Yb))}b={W:b,port:c,o:e,ab:[]};Z.L.$b(a,b);Z.L.zd(a,b);2===a.type&&"undefined"!==typeof a.ya&&b.ab.push(new Uint8Array([255,255,255,255,112,111,114,116,(a.ya&65280)>>8,a.ya&255]));return b},gb:function(a,b,c){return a.Ma[b+":"+c]},$b:function(a,b){a.Ma[b.W+":"+b.port]=b},Bc:function(a,b){delete a.Ma[b.W+ +":"+b.port]},zd:function(a,b){function c(){p.websocket.P("open",a.A.C);try{for(var c=b.ab.shift();c;)b.o.send(c),c=b.ab.shift()}catch(e){b.o.close()}}function e(c){w("string"!==typeof c&&c.byteLength!==g);var c=new Uint8Array(c),e=f;f=m;e&&10===c.length&&255===c[0]&&255===c[1]&&255===c[2]&&255===c[3]&&112===c[4]&&111===c[5]&&114===c[6]&&116===c[7]?(c=c[8]<<8|c[9],Z.L.Bc(a,b),b.port=c,Z.L.$b(a,b)):(a.ua.push({W:b.W,port:b.port,data:c}),p.websocket.P("message",a.A.C))}var f=i;t?(b.o.on("open",c),b.o.on("message", +function(a,b){b.binary&&e((new Uint8Array(a)).buffer)}),b.o.on("close",function(){p.websocket.P("close",a.A.C)}),b.o.on("error",function(){a.error=U.Wb;p.websocket.P("error",[a.A.C,a.error,"ECONNREFUSED: Connection refused"])})):(b.o.onopen=c,b.o.onclose=function(){p.websocket.P("close",a.A.C)},b.o.onmessage=function(a){e(a.data)},b.o.onerror=function(){a.error=U.Wb;p.websocket.P("error",[a.A.C,a.error,"ECONNREFUSED: Connection refused"])})},zc:function(a){if(1===a.type&&a.G)return a.Kb.length?65: +0;var b=0,c=1===a.type?Z.L.gb(a,a.Y,a.Z):k;if(a.ua.length||!c||c&&c.o.readyState===c.o.Pa||c&&c.o.readyState===c.o.CLOSED)b|=65;if(!c||c&&c.o.readyState===c.o.OPEN)b|=4;if(c&&c.o.readyState===c.o.Pa||c&&c.o.readyState===c.o.CLOSED)b|=16;return b},Ha:function(a,b,c){switch(b){case 21531:return b=0,a.ua.length&&(b=a.ua[0].data.length),K[c>>2]=b,0;default:return U.B}},close:function(a){if(a.G){try{a.G.close()}catch(b){}a.G=k}for(var c=Object.keys(a.Ma),e=0;e>0]=c;if(-1==Ab(Cb(b),Eb.Cc,1)){if(c=B.pc(b))c.error=i;return-1}return c}function Fb(a){Fb.$c||(E=E+4095&-4096,Fb.$c=i,w(z.bb),Fb.Wc=z.bb,z.bb=function(){A("cannot dynamically allocate, sbrk now has control")});var b=E;0!=a&&Fb.Wc(a);return b}p._memset=Gb;function Hb(a,b,c){window._broadwayOnPictureDecoded(a,b,c)}p._broadwayOnPictureDecoded=Hb;function Ib(){window._broadwayOnHeadersDecoded()}p._broadwayOnHeadersDecoded=Ib; +function Jb(a,b){Kb=a;Lb=b;if(!Mb)return 1;0==a?(Nb=function(){setTimeout(Ob,b)},Pb="timeout"):1==a&&(Nb=function(){Qb(Ob)},Pb="rAF");return 0} +function Rb(a,b,c,e){p.noExitRuntime=i;w(!Mb,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");Mb=a;Sb=e;var f=Tb;Ob=function(){if(!H)if(0=bc;)bc+=1E3/60;b=Math.max(bc-b,0);setTimeout(a,b)}function Qb(a){"undefined"===typeof window?cc(a):(window.requestAnimationFrame||(window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||cc),window.requestAnimationFrame(a))} +function xb(a){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",bmp:"image/bmp",ogg:"audio/ogg",wav:"audio/wav",mp3:"audio/mpeg"}[a.substr(a.lastIndexOf(".")+1)]} +function yb(a,b,c){function e(){c?c():d('Loading data file "'+a+'" failed.')}var f=new XMLHttpRequest;f.open("GET",a,i);f.responseType="arraybuffer";f.onload=function(){if(200==f.status||0==f.status&&f.response){var c=f.response;w(c,'Loading data file "'+a+'" failed (no arrayBuffer).');b(new Uint8Array(c));Za()}else e()};f.onerror=e;f.send(k);Ya()}var dc=[];function ec(){var a=p.canvas;dc.forEach(function(b){b(a.width,a.height)})} +function fc(a,b,c){b&&c?(a.ae=b,a.Ad=c):(b=a.ae,c=a.Ad);var e=b,f=c;p.forcedAspectRatio&&0>2]=0;R.unshift({ja:n()});Qa.push({ja:n()});var lb=new z.Da;t&&((null)("fs"),process.platform.match(/^win/));R.push({ja:function(){Z.root=B.F(Z,{},k)}}); +Eb.Cc=M([0],"i8",L); +p.requestFullScreen=function(a,b){function c(){Yb=m;var a=e.parentNode;(document.webkitFullScreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.mozFullscreenElement||document.fullScreenElement||document.fullscreenElement||document.msFullScreenElement||document.msFullscreenElement||document.webkitCurrentFullScreenElement)===a?(e.cc=document.cancelFullScreen||document.mozCancelFullScreen||document.webkitCancelFullScreen||document.msExitFullscreen||document.exitFullscreen|| +n(),e.cc=e.cc.bind(document),$b&&e.Pb(),Yb=i,ac&&("undefined"!=typeof SDL&&(a=Ha[SDL.screen+0*z.ia>>2],K[SDL.screen+0*z.ia>>2]=a|8388608),ec())):(a.parentNode.insertBefore(e,a),a.parentNode.removeChild(a),ac&&("undefined"!=typeof SDL&&(a=Ha[SDL.screen+0*z.ia>>2],K[SDL.screen+0*z.ia>>2]=a&-8388609),ec()));if(p.onFullScreen)p.onFullScreen(Yb);fc(e)}$b=a;ac=b;"undefined"===typeof $b&&($b=i);"undefined"===typeof ac&&(ac=m);var e=p.canvas;Zb||(Zb=i,document.addEventListener("fullscreenchange",c,m),document.addEventListener("mozfullscreenchange", +c,m),document.addEventListener("webkitfullscreenchange",c,m),document.addEventListener("MSFullscreenChange",c,m));var f=document.createElement("div");e.parentNode.insertBefore(f,e);f.appendChild(e);f.Td=f.requestFullScreen||f.mozRequestFullScreen||f.msRequestFullscreen||(f.webkitRequestFullScreen?function(){f.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}:k);f.Td()};p.requestAnimationFrame=function(a){Qb(a)};p.setCanvasSize=function(a,b,c){fc(p.canvas,a,b);c||ec()}; +p.pauseMainLoop=function(){Nb=k;Tb++};p.resumeMainLoop=function(){Tb++;var a=Kb,b=Lb,c=Mb;Mb=k;Rb(c,0,m,Sb);Jb(a,b)};p.getUserMedia=function(){window.qc||(window.qc=navigator.getUserMedia||navigator.mozGetUserMedia);window.qc(g)};Ja=y=z.ub(D);Ka=Ja+Ma;La=E=z.ub(Ka);w(La>2],a=Db(a,b);return 0>a?a:0>Eb(10,b)?-1:a+1},_fflush:n(),_fputc:Eb,_send:function(a,b,c){return!Z.wd(a)?(V(U.V),-1):Ab(a,b,c)},_pwrite:function(a,b,c,e){a=B.qa(a);if(!a)return V(U.V),-1;try{return B.write(a,I,b,c,e)}catch(f){return B.sc(f),-1}},_fputs:Db,_emscripten_set_main_loop:Rb, +_abort:function(){p.abort()},___setErrNo:V,_sbrk:Fb,_mkport:zb,_emscripten_set_main_loop_timing:Jb,_emscripten_memcpy_big:function(a,b,c){N.set(N.subarray(b,b+c),a);return a},_fileno:Cb,_broadwayOnHeadersDecoded:Ib,_write:Ab,_time:function(a){var b=Date.now()/1E3|0;a&&(K[a>>2]=b);return b},_sysconf:function(a){switch(a){case 30:return 4096;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 79:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809; +case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32; +case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1E3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:return"object"===typeof navigator?navigator.hardwareConcurrency||1:1}V(U.B);return-1}, +___errno_location:function(){return bb},STACKTOP:y,STACK_MAX:Ka,tempDoublePtr:$a,ABORT:H,NaN:NaN,Infinity:Infinity};// EMSCRIPTEN_START_ASM +var $=(function(global,env,buffer) { +"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=0;var n=0;var o=0;var p=0;var q=+env.NaN,r=+env.Infinity;var s=0,t=0,u=0,v=0,w=0.0,x=0,y=0,z=0,A=0.0;var B=0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=global.Math.floor;var M=global.Math.abs;var N=global.Math.sqrt;var O=global.Math.pow;var P=global.Math.cos;var Q=global.Math.sin;var R=global.Math.tan;var S=global.Math.acos;var T=global.Math.asin;var U=global.Math.atan;var V=global.Math.atan2;var W=global.Math.exp;var X=global.Math.log;var Y=global.Math.ceil;var Z=global.Math.imul;var _=env.abort;var $=env.assert;var aa=env.min;var ba=env.invoke_viiiii;var ca=env._broadwayOnPictureDecoded;var da=env._puts;var ea=env._fflush;var fa=env._fputc;var ga=env._send;var ha=env._pwrite;var ia=env._fputs;var ja=env._emscripten_set_main_loop;var ka=env._abort;var la=env.___setErrNo;var ma=env._sbrk;var na=env._mkport;var oa=env._emscripten_set_main_loop_timing;var pa=env._emscripten_memcpy_big;var qa=env._fileno;var ra=env._broadwayOnHeadersDecoded;var sa=env._write;var ta=env._time;var ua=env._sysconf;var va=env.___errno_location;var wa=0.0; +// EMSCRIPTEN_START_FUNCS +function Sb(a,f,g,h,j,k){a=a|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0;X=i;i=i+32|0;W=X;p=c[j+4>>2]|0;V=(h>>>0)/(p>>>0)|0;U=V<<4;V=h-(Z(V,p)|0)<<4;c[W+4>>2]=p;c[W+8>>2]=c[j+8>>2];p=c[a>>2]|0;do if((p|0)==1|(p|0)==0){A=c[f+144>>2]|0;l=a+4|0;n=c[a+200>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){o=n+152|0;o=e[o>>1]|e[o+2>>1]<<16;m=1;v=o&65535;o=o>>>16&65535;s=c[n+104>>2]|0}else{m=1;v=0;o=0;s=-1}else{m=0;v=0;o=0;s=-1}n=c[a+204>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){w=n+172|0;w=e[w>>1]|e[w+2>>1]<<16;u=w&65535;q=1;r=c[n+108>>2]|0;w=w>>>16&65535}else{u=0;q=1;r=-1;w=0}else{u=0;q=0;r=-1;w=0}do if(!p)if(!((m|0)==0|(q|0)==0)){if((s|0)==0?((o&65535)<<16|v&65535|0)==0:0){n=0;o=0;break}if((r|0)==0?((w&65535)<<16|u&65535|0)==0:0){n=0;o=0}else T=16}else{n=0;o=0}else T=16;while(0);if((T|0)==16){y=b[f+160>>1]|0;z=b[f+162>>1]|0;n=c[a+208>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[l>>2]|0):0)if((c[n>>2]|0)>>>0<6){t=n+172|0;p=c[n+108>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;T=25}else{p=-1;t=0;T=25}else T=20;do if((T|0)==20){p=c[a+212>>2]|0;if((p|0)!=0?(c[p+4>>2]|0)==(c[l>>2]|0):0){if((c[p>>2]|0)>>>0>=6){p=-1;t=0;T=25;break}t=p+192|0;p=c[p+112>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;T=25;break}if((m|0)==0|(q|0)!=0){p=-1;t=0;T=25}else n=v}while(0);do if((T|0)==25){m=(s|0)==(A|0);n=(r|0)==(A|0);if(((n&1)+(m&1)+((p|0)==(A|0)&1)|0)==1){if(m|n){n=m?v:u;o=m?o:w;break}n=t&65535;o=t>>>16&65535;break}n=v<<16>>16;l=u<<16>>16;p=t<<16>>16;if(u<<16>>16>v<<16>>16)m=l;else{m=n;n=(l|0)<(n|0)?l:n}if((m|0)<(p|0))p=m;else p=(n|0)>(p|0)?n:p;n=o<<16>>16;m=w<<16>>16;l=t>>16;if(w<<16>>16>o<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=p&65535;o=o&65535}while(0);n=(n&65535)+(y&65535)|0;o=(o&65535)+(z&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}else{n=n&65535;o=o&65535}}l=ic(g,A)|0;if(!l){G=1;i=X;return G|0}else{G=a+132|0;E=a+136|0;D=a+140|0;C=a+144|0;B=a+148|0;z=a+152|0;y=a+156|0;x=a+160|0;w=a+164|0;v=a+168|0;m=a+172|0;p=a+176|0;q=a+180|0;r=a+184|0;s=a+188|0;F=a+192|0;b[a+192>>1]=n;b[a+194>>1]=o;F=e[F>>1]|e[F+2>>1]<<16;b[s>>1]=F;b[s+2>>1]=F>>>16;b[r>>1]=F;b[r+2>>1]=F>>>16;b[q>>1]=F;b[q+2>>1]=F>>>16;b[p>>1]=F;b[p+2>>1]=F>>>16;b[m>>1]=F;b[m+2>>1]=F>>>16;b[v>>1]=F;b[v+2>>1]=F>>>16;b[w>>1]=F;b[w+2>>1]=F>>>16;b[x>>1]=F;b[x+2>>1]=F>>>16;b[y>>1]=F;b[y+2>>1]=F>>>16;b[z>>1]=F;b[z+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+100>>2]=A;c[a+104>>2]=A;c[a+108>>2]=A;c[a+112>>2]=A;c[a+116>>2]=l;c[a+120>>2]=l;c[a+124>>2]=l;c[a+128>>2]=l;c[W>>2]=l;dc(k,a+132|0,W,V,U,0,0,16,16);break}}else if((p|0)==3){x=b[f+160>>1]|0;y=b[f+162>>1]|0;C=c[f+144>>2]|0;u=a+4|0;o=c[a+200>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){w=o+152|0;w=e[w>>1]|e[w+2>>1]<<16;n=1;s=w&65535;w=w>>>16&65535;o=c[o+104>>2]|0}else{n=1;s=0;w=0;o=-1}else{n=0;s=0;w=0;o=-1}a:do if((o|0)==(C|0)){n=s;o=w}else{o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){G=o+172|0;G=e[G>>1]|e[G+2>>1]<<16;t=o+188|0;p=c[o+108>>2]|0;l=c[o+112>>2]|0;n=G&65535;o=G>>>16&65535;t=e[t>>1]|e[t+2>>1]<<16}else{p=-1;l=-1;n=0;o=0;t=0}else T=107;do if((T|0)==107){o=c[a+212>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0){if((c[o>>2]|0)>>>0>=6){p=-1;l=-1;n=0;o=0;t=0;break}t=o+192|0;p=-1;l=c[o+112>>2]|0;n=0;o=0;t=e[t>>1]|e[t+2>>1]<<16;break}if(!n){p=-1;l=-1;n=0;o=0;t=0}else{n=s;o=w;break a}}while(0);m=(p|0)==(C|0);if(((m&1)+((l|0)==(C|0)&1)|0)==1){if(m)break;n=t&65535;o=t>>>16&65535;break}l=s<<16>>16;p=n<<16>>16;q=t<<16>>16;if(n<<16>>16>s<<16>>16){m=p;n=l}else{m=l;n=(p|0)<(l|0)?p:l}if((m|0)<(q|0))q=m;else q=(n|0)>(q|0)?n:q;n=w<<16>>16;m=o<<16>>16;l=t>>16;if(o<<16>>16>w<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=q&65535;o=o&65535}while(0);n=(n&65535)+(x&65535)|0;o=(o&65535)+(y&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}m=ic(g,C)|0;if(!m){G=1;i=X;return G|0}x=a+132|0;z=a+136|0;A=a+140|0;y=a+144|0;G=a+164|0;F=a+168|0;E=a+172|0;w=a+176|0;b[a+176>>1]=n;b[a+178>>1]=o;w=e[w>>1]|e[w+2>>1]<<16;b[E>>1]=w;b[E+2>>1]=w>>>16;b[F>>1]=w;b[F+2>>1]=w>>>16;b[G>>1]=w;b[G+2>>1]=w>>>16;b[y>>1]=w;b[y+2>>1]=w>>>16;b[A>>1]=w;b[A+2>>1]=w>>>16;b[z>>1]=w;b[z+2>>1]=w>>>16;b[x>>1]=w;b[x+2>>1]=w>>>16;c[a+100>>2]=C;c[a+108>>2]=C;x=a+116|0;c[x>>2]=m;c[a+124>>2]=m;z=b[f+164>>1]|0;A=b[f+166>>1]|0;y=c[f+148>>2]|0;o=c[a+208>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){r=o+172|0;o=c[o+108>>2]|0;p=1;r=e[r>>1]|e[r+2>>1]<<16}else{o=-1;p=1;r=0}else{o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[u>>2]|0):0)if((c[o>>2]|0)>>>0<6){r=o+176|0;o=c[o+108>>2]|0;p=1;r=e[r>>1]|e[r+2>>1]<<16}else{o=-1;p=1;r=0}else{o=-1;p=0;r=0}}do if((o|0)!=(y|0)){s=w&65535;o=w>>>16;v=o&65535;n=c[a+204>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[u>>2]|0):0)if((c[n>>2]|0)>>>0<6){u=n+188|0;u=e[u>>1]|e[u+2>>1]<<16;p=c[n+112>>2]|0;l=u&65535;u=u>>>16&65535}else{p=-1;l=0;u=0}else if(!p){m=w;break}else{p=-1;l=0;u=0}m=(C|0)==(y|0);n=(p|0)==(y|0);if(((n&1)+(m&1)|0)==1){if(m){m=w;break}if(n){o=u&65535;m=o<<16|l&65535;break}else{m=r;o=r>>>16;break}}o=w<<16>>16;p=l<<16>>16;q=r<<16>>16;if(l<<16>>16>s<<16>>16)m=p;else{m=o;o=(p|0)<(o|0)?p:o}if((m|0)>=(q|0))m=(o|0)>(q|0)?o:q;n=w>>16;l=u<<16>>16;p=r>>16;if(u<<16>>16>v<<16>>16)o=l;else{o=n;n=(l|0)<(n|0)?l:n}if((o|0)>=(p|0))o=(n|0)>(p|0)?n:p}else{m=r;o=r>>>16}while(0);m=(m&65535)+(z&65535)|0;n=(o&65535)+(A&65535)|0;if(((m<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((n<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}o=ic(g,y)|0;if(!o){G=1;i=X;return G|0}else{G=a+148|0;E=a+152|0;D=a+156|0;C=a+160|0;B=a+180|0;A=a+184|0;z=a+188|0;F=a+192|0;b[a+192>>1]=m;b[a+194>>1]=n;F=e[F>>1]|e[F+2>>1]<<16;b[z>>1]=F;b[z+2>>1]=F>>>16;b[A>>1]=F;b[A+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+104>>2]=y;c[a+112>>2]=y;F=a+120|0;c[F>>2]=o;c[a+128>>2]=o;c[W>>2]=c[x>>2];dc(k,a+132|0,W,V,U,0,0,8,16);c[W>>2]=c[F>>2];dc(k,G,W,V,U,8,0,8,16);break}}else if((p|0)==2){z=b[f+160>>1]|0;A=b[f+162>>1]|0;C=c[f+144>>2]|0;B=a+4|0;o=c[a+204>>2]|0;if((o|0)!=0?(c[o+4>>2]|0)==(c[B>>2]|0):0)if((c[o>>2]|0)>>>0<6){w=o+172|0;w=e[w>>1]|e[w+2>>1]<<16;m=1;o=c[o+108>>2]|0;r=w&65535;w=w>>>16&65535}else{m=1;o=-1;r=0;w=0}else{m=0;o=-1;r=0;w=0}b:do if((o|0)==(C|0)){n=r;o=w}else{n=c[a+200>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0)if((c[n>>2]|0)>>>0<6){o=n+152|0;o=e[o>>1]|e[o+2>>1]<<16;q=1;s=o&65535;o=o>>>16&65535;p=c[n+104>>2]|0}else{q=1;s=0;o=0;p=-1}else{q=0;s=0;o=0;p=-1}n=c[a+208>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0)if((c[n>>2]|0)>>>0<6){t=n+172|0;n=c[n+108>>2]|0;t=e[t>>1]|e[t+2>>1]<<16}else{n=-1;t=0}else T=54;do if((T|0)==54){n=c[a+212>>2]|0;if((n|0)!=0?(c[n+4>>2]|0)==(c[B>>2]|0):0){if((c[n>>2]|0)>>>0>=6){n=-1;t=0;break}t=n+192|0;n=c[n+112>>2]|0;t=e[t>>1]|e[t+2>>1]<<16;break}if((q|0)==0|(m|0)!=0){n=-1;t=0}else{n=s;break b}}while(0);m=(p|0)==(C|0);if((((n|0)==(C|0)&1)+(m&1)|0)==1){if(m){n=m?s:r;o=m?o:w;break}n=t&65535;o=t>>>16&65535;break}n=s<<16>>16;l=r<<16>>16;p=t<<16>>16;if(r<<16>>16>s<<16>>16)m=l;else{m=n;n=(l|0)<(n|0)?l:n}if((m|0)<(p|0))q=m;else q=(n|0)>(p|0)?n:p;n=o<<16>>16;m=w<<16>>16;l=t>>16;if(w<<16>>16>o<<16>>16)o=m;else{o=n;n=(m|0)<(n|0)?m:n}if((o|0)>=(l|0))o=(n|0)>(l|0)?n:l;n=q&65535;o=o&65535}while(0);n=(n&65535)+(z&65535)|0;o=(o&65535)+(A&65535)|0;if(((n<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((o<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}m=ic(g,C)|0;if(!m){G=1;i=X;return G|0}A=a+132|0;x=a+136|0;y=a+140|0;z=a+144|0;q=a+148|0;p=a+152|0;G=a+156|0;v=a+160|0;b[a+160>>1]=n;b[a+162>>1]=o;v=e[v>>1]|e[v+2>>1]<<16;b[G>>1]=v;b[G+2>>1]=v>>>16;b[p>>1]=v;b[p+2>>1]=v>>>16;b[q>>1]=v;b[q+2>>1]=v>>>16;b[z>>1]=v;b[z+2>>1]=v>>>16;b[y>>1]=v;b[y+2>>1]=v>>>16;b[x>>1]=v;b[x+2>>1]=v>>>16;b[A>>1]=v;b[A+2>>1]=v>>>16;c[a+100>>2]=C;c[a+104>>2]=C;A=a+116|0;c[A>>2]=m;c[a+120>>2]=m;x=b[f+164>>1]|0;y=b[f+166>>1]|0;z=c[f+148>>2]|0;q=c[a+200>>2]|0;p=(q|0)==0;if((!p?(c[q+4>>2]|0)==(c[B>>2]|0):0)?(c[q>>2]|0)>>>0<6:0){w=q+184|0;w=e[w>>1]|e[w+2>>1]<<16;r=w&65535;w=w>>>16&65535;o=c[q+112>>2]|0}else{r=0;w=0;o=-1}do if((o|0)!=(z|0)){s=v&65535;n=v>>>16;u=n&65535;if((!p?(c[q+4>>2]|0)==(c[B>>2]|0):0)?(c[q>>2]|0)>>>0<6:0){t=q+160|0;p=c[q+104>>2]|0;t=e[t>>1]|e[t+2>>1]<<16}else{p=-1;t=0}o=(C|0)==(z|0);if((((p|0)==(z|0)&1)+(o&1)|0)==1){m=o?v:t;o=o?n:t>>>16;break}o=r<<16>>16;p=v<<16>>16;q=t<<16>>16;if(s<<16>>16>r<<16>>16)m=p;else{m=o;o=(p|0)<(o|0)?p:o}if((m|0)>=(q|0))m=(o|0)>(q|0)?o:q;n=w<<16>>16;l=v>>16;p=t>>16;if(u<<16>>16>w<<16>>16)o=l;else{o=n;n=(l|0)<(n|0)?l:n}if((o|0)>=(p|0))o=(n|0)>(p|0)?n:p}else{o=w&65535;m=o<<16|r&65535}while(0);m=(m&65535)+(x&65535)|0;n=(o&65535)+(y&65535)|0;if(((m<<16>>16)+8192|0)>>>0>16383){G=1;i=X;return G|0}if(((n<<16>>16)+2048|0)>>>0>4095){G=1;i=X;return G|0}o=ic(g,z)|0;if(!o){G=1;i=X;return G|0}else{G=a+164|0;E=a+168|0;D=a+172|0;C=a+176|0;B=a+180|0;y=a+184|0;x=a+188|0;F=a+192|0;b[a+192>>1]=m;b[a+194>>1]=n;F=e[F>>1]|e[F+2>>1]<<16;b[x>>1]=F;b[x+2>>1]=F>>>16;b[y>>1]=F;b[y+2>>1]=F>>>16;b[B>>1]=F;b[B+2>>1]=F>>>16;b[C>>1]=F;b[C+2>>1]=F>>>16;b[D>>1]=F;b[D+2>>1]=F>>>16;b[E>>1]=F;b[E+2>>1]=F>>>16;b[G>>1]=F;b[G+2>>1]=F>>>16;c[a+108>>2]=z;c[a+112>>2]=z;F=a+124|0;c[F>>2]=o;c[a+128>>2]=o;c[W>>2]=c[A>>2];dc(k,a+132|0,W,V,U,0,0,16,8);c[W>>2]=c[F>>2];dc(k,G,W,V,U,0,8,16,8);break}}else{S=a+4|0;H=0;c:while(1){D=f+(H<<2)+176|0;G=eb(c[D>>2]|0)|0;E=f+(H<<2)+192|0;c[a+(H<<2)+100>>2]=c[E>>2];F=ic(g,c[E>>2]|0)|0;c[a+(H<<2)+116>>2]=F;if(!F){l=1;T=212;break}if(G){J=H<<2;K=a+(J<<2)+132|0;O=a+(J<<2)+134|0;P=J|1;L=a+(P<<2)+132|0;P=a+(P<<2)+134|0;Q=J|2;M=a+(Q<<2)+132|0;Q=a+(Q<<2)+134|0;R=J|3;N=a+(R<<2)+132|0;R=a+(R<<2)+134|0;I=0;do{C=b[f+(H<<4)+(I<<2)+208>>1]|0;B=b[f+(H<<4)+(I<<2)+210>>1]|0;F=hb(c[D>>2]|0)|0;n=c[E>>2]|0;s=ub(a,c[6288+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;r=d[6288+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((s|0)!=0?(c[s+4>>2]|0)==(c[S>>2]|0):0)if((c[s>>2]|0)>>>0<6){q=s+(r<<2)+132|0;q=e[q>>1]|e[q+2>>1]<<16;A=c[s+(r>>>2<<2)+100>>2]|0;o=q&65535;z=1;q=q>>>16&65535}else{A=-1;o=0;z=1;q=0}else{A=-1;o=0;z=0;q=0}v=ub(a,c[5776+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;l=d[5776+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((v|0)!=0?(c[v+4>>2]|0)==(c[S>>2]|0):0)if((c[v>>2]|0)>>>0<6){p=v+(l<<2)+132|0;p=e[p>>1]|e[p+2>>1]<<16;y=1;x=c[v+(l>>>2<<2)+100>>2]|0;m=p&65535;p=p>>>16&65535}else{y=1;x=-1;m=0;p=0}else{y=0;x=-1;m=0;p=0}w=ub(a,c[5264+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;v=d[5264+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((w|0)!=0?(c[w+4>>2]|0)==(c[S>>2]|0):0)if((c[w>>2]|0)>>>0<6){z=w+(v<<2)+132|0;z=e[z>>1]|e[z+2>>1]<<16;v=c[w+(v>>>2<<2)+100>>2]|0;T=180}else{z=0;v=-1;T=180}else T=175;do if((T|0)==175){T=0;w=ub(a,c[4752+(H<<7)+(F<<5)+(I<<3)>>2]|0)|0;v=d[4752+(H<<7)+(F<<5)+(I<<3)+4>>0]|0;if((w|0)!=0?(c[w+4>>2]|0)==(c[S>>2]|0):0){if((c[w>>2]|0)>>>0>=6){z=0;v=-1;T=180;break}z=w+(v<<2)+132|0;z=e[z>>1]|e[z+2>>1]<<16;v=c[w+(v>>>2<<2)+100>>2]|0;T=180;break}if((z|0)==0|(y|0)!=0){z=0;v=-1;T=180}else{v=o;t=q}}while(0);do if((T|0)==180){l=(A|0)==(n|0);w=(x|0)==(n|0);if(((w&1)+(l&1)+((v|0)==(n|0)&1)|0)==1){if(l|w){v=l?o:m;t=l?q:p;break}v=z&65535;t=z>>>16&65535;break}u=o<<16>>16;w=m<<16>>16;l=z<<16>>16;if(m<<16>>16>o<<16>>16)v=w;else{v=u;u=(w|0)<(u|0)?w:u}if((v|0)<(l|0))w=v;else w=(u|0)>(l|0)?u:l;t=q<<16>>16;v=p<<16>>16;l=z>>16;if(p<<16>>16>q<<16>>16)s=v;else{s=t;t=(v|0)<(t|0)?v:t}if((s|0)>=(l|0))s=(t|0)>(l|0)?t:l;v=w&65535;t=s&65535}while(0);C=(v&65535)+(C&65535)|0;q=C&65535;s=(t&65535)+(B&65535)|0;r=s&65535;if(((C<<16>>16)+8192|0)>>>0>16383){l=1;T=212;break c}if(((s<<16>>16)+2048|0)>>>0>4095){l=1;T=212;break c}if(!F){b[K>>1]=q;b[O>>1]=r;b[L>>1]=q;b[P>>1]=r;b[M>>1]=q;b[Q>>1]=r;b[N>>1]=q;b[R>>1]=r}else if((F|0)==1){F=(I<<1)+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r;F=F|1;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}else if((F|0)==2){F=I+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r;F=F+2|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}else if((F|0)==3){F=I+J|0;b[a+(F<<2)+132>>1]=q;b[a+(F<<2)+134>>1]=r}I=I+1|0}while(I>>>0>>0)}H=H+1|0;if(H>>>0>=4){T=201;break}}if((T|0)==201){o=0;do{c[W>>2]=c[a+(o<<2)+116>>2];m=hb(c[f+(o<<2)+176>>2]|0)|0;l=o<<3&8;n=o>>>0<2?0:8;if(!m)dc(k,a+(o<<2<<2)+132|0,W,V,U,l,n,8,8);else if((m|0)==1){G=o<<2;dc(k,a+(G<<2)+132|0,W,V,U,l,n,8,4);dc(k,a+((G|2)<<2)+132|0,W,V,U,l,n|4,8,4)}else if((m|0)==2){G=o<<2;dc(k,a+(G<<2)+132|0,W,V,U,l,n,4,8);dc(k,a+((G|1)<<2)+132|0,W,V,U,l|4,n,4,8)}else{E=o<<2;dc(k,a+(E<<2)+132|0,W,V,U,l,n,4,4);F=l|4;dc(k,a+((E|1)<<2)+132|0,W,V,U,F,n,4,4);G=n|4;dc(k,a+((E|2)<<2)+132|0,W,V,U,l,G,4,4);dc(k,a+((E|3)<<2)+132|0,W,V,U,F,G,4,4)}o=o+1|0}while((o|0)!=4)}else if((T|0)==212){i=X;return l|0}}while(0);if((c[a+196>>2]|0)>>>0>1){G=0;i=X;return G|0}if(!(c[a>>2]|0)){sc(j,k);G=0;i=X;return G|0}else{tc(j,h,k,f+328|0);G=0;i=X;return G|0}return 0}function Tb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;B=i;i=i+144|0;m=B;if((e|0)>=0?!((e+1+k|0)>>>0>g>>>0|(f|0)<0|(l+f|0)>>>0>h>>>0):0)m=b;else{A=k+1|0;Ub(b,m,e,f,g,h,A,l,A);Ub(b+(Z(h,g)|0)|0,m+(Z(A,l)|0)|0,e,f,g,h,A,l,A);h=l;g=A;e=0;f=0}A=8-j|0;v=l>>>1;z=(v|0)==0;w=k>>>1;y=(w|0)==0;x=16-k|0;u=(g<<1)-k|0;s=g+1|0;t=g+2|0;p=w<<1;r=0;do{l=m+((Z((Z(r,h)|0)+f|0,g)|0)+e)|0;if(!(z|y)){q=c+(r<<6)|0;o=v;while(1){k=q;b=l;n=w;while(1){D=d[b>>0]|0;E=d[b+s>>0]|0;F=b;b=b+2|0;C=d[F+1>>0]|0;a[k+8>>0]=(((Z(E,j)|0)+(Z(d[F+g>>0]|0,A)|0)<<3)+32|0)>>>6;a[k>>0]=(((Z(C,j)|0)+(Z(D,A)|0)<<3)+32|0)>>>6;D=d[b>>0]|0;a[k+9>>0]=(((Z(d[F+t>>0]|0,j)|0)+(Z(E,A)|0)<<3)+32|0)>>>6;a[k+1>>0]=(((Z(D,j)|0)+(Z(C,A)|0)<<3)+32|0)>>>6;n=n+-1|0;if(!n)break;else k=k+2|0}o=o+-1|0;if(!o)break;else{q=q+(p+x)|0;l=l+(p+u)|0}}}r=r+1|0}while((r|0)!=2);i=B;return}function Ub(a,b,c,d,e,f,g,h,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;k=g+c|0;o=h+d|0;s=(c|0)<0|(k|0)>(e|0)?2:1;m=(o|0)<0?0-h|0:d;d=(k|0)<0?0-g|0:c;m=(m|0)>(f|0)?f:m;d=(d|0)>(e|0)?e:d;k=d+g|0;l=m+h|0;if((d|0)>0)a=a+d|0;if((m|0)>0)a=a+(Z(m,e)|0)|0;r=(d|0)<0?0-d|0:0;q=(k|0)>(e|0)?k-e|0:0;p=g-r-q|0;g=0-m|0;m=(m|0)<0?g:0;c=l-f|0;n=(l|0)>(f|0)?c:0;k=h-m|0;d=k-n|0;if(m){m=h+-1-((o|0)>0?o:0)|0;l=~f;l=(m|0)>(l|0)?m:l;m=~l;m=Z(l+((m|0)>0?m:0)+1|0,j)|0;l=b;while(1){xa[s&3](a,l,r,p,q);g=g+-1|0;if(!g)break;else l=l+j|0}b=b+m|0}if((k|0)!=(n|0)){l=h+-1|0;g=l-((o|0)>0?o:0)|0;k=~f;k=(g|0)>(k|0)?g:k;l=l-k|0;g=~k;g=h+f+-1-((l|0)<(f|0)?f:l)-k-((g|0)>0?g:0)|0;k=Z(g,j)|0;g=Z(g,e)|0;l=b;m=a;while(1){xa[s&3](m,l,r,p,q);d=d+-1|0;if(!d)break;else{l=l+j|0;m=m+e|0}}b=b+k|0;a=a+g|0}a=a+(0-e)|0;if(!n){i=t;return}while(1){xa[s&3](a,b,r,p,q);c=c+-1|0;if(!c)break;else b=b+j|0}i=t;return}function Vb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;C=i;i=i+144|0;m=C;if(((e|0)>=0?!((k+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+1+l|0)>>>0<=h>>>0:0)m=b;else{A=l+1|0;Ub(b,m,e,f,g,h,k,A,k);Ub(b+(Z(h,g)|0)|0,m+(Z(A,k)|0)|0,e,f,g,h,k,A,k);h=A;g=k;e=0;f=0}B=8-j|0;w=l>>>1;A=(w|0)==0;x=k>>>1;z=(x|0)==0;y=16-k|0;v=g<<1;u=v-k|0;t=v|1;s=g+1|0;p=x<<1;r=0;do{l=m+((Z((Z(r,h)|0)+f|0,g)|0)+e)|0;if(!(A|z)){q=c+(r<<6)|0;o=w;while(1){k=q;b=l;n=x;while(1){D=d[b+g>>0]|0;E=d[b>>0]|0;a[k+8>>0]=(((Z(D,B)|0)+(Z(d[b+v>>0]|0,j)|0)<<3)+32|0)>>>6;a[k>>0]=(((Z(E,B)|0)+(Z(D,j)|0)<<3)+32|0)>>>6;D=d[b+s>>0]|0;E=d[b+1>>0]|0;a[k+9>>0]=(((Z(D,B)|0)+(Z(d[b+t>>0]|0,j)|0)<<3)+32|0)>>>6;a[k+1>>0]=(((Z(E,B)|0)+(Z(D,j)|0)<<3)+32|0)>>>6;n=n+-1|0;if(!n)break;else{k=k+2|0;b=b+2|0}}o=o+-1|0;if(!o)break;else{q=q+(p+y)|0;l=l+(p+u)|0}}}r=r+1|0}while((r|0)!=2);i=C;return}function Wb(b,c,e,f,g,h,j,k,l,m){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;I=i;i=i+176|0;n=I;if(((e|0)>=0?!((e+1+l|0)>>>0>g>>>0|(f|0)<0):0)?(f+1+m|0)>>>0<=h>>>0:0)n=b;else{B=l+1|0;A=m+1|0;Ub(b,n,e,f,g,h,B,A,B);Ub(b+(Z(h,g)|0)|0,n+(Z(A,B)|0)|0,e,f,g,h,B,A,B);h=A;g=B;e=0;f=0}G=8-j|0;H=8-k|0;B=m>>>1;E=(B|0)==0;A=g<<1;C=l>>>1;F=(C|0)==0;D=16-l|0;z=A-l|0;v=g+1|0;w=A|1;x=g+2|0;y=A+2|0;s=C<<1;u=0;do{l=n+((Z((Z(u,h)|0)+f|0,g)|0)+e)|0;if(!(E|F)){t=c+(u<<6)|0;r=B;while(1){p=d[l+g>>0]|0;m=t;b=l;o=(Z(p,k)|0)+(Z(d[l>>0]|0,H)|0)|0;p=(Z(d[l+A>>0]|0,k)|0)+(Z(p,H)|0)|0;q=C;while(1){K=d[b+v>>0]|0;J=(Z(K,k)|0)+(Z(d[b+1>>0]|0,H)|0)|0;K=(Z(d[b+w>>0]|0,k)|0)+(Z(K,H)|0)|0;M=((Z(o,G)|0)+32+(Z(J,j)|0)|0)>>>6;a[m+8>>0]=((Z(p,G)|0)+32+(Z(K,j)|0)|0)>>>6;a[m>>0]=M;M=b;b=b+2|0;L=d[M+x>>0]|0;o=(Z(L,k)|0)+(Z(d[b>>0]|0,H)|0)|0;p=(Z(d[M+y>>0]|0,k)|0)+(Z(L,H)|0)|0;J=((Z(J,G)|0)+32+(Z(o,j)|0)|0)>>>6;a[m+9>>0]=((Z(K,G)|0)+32+(Z(p,j)|0)|0)>>>6;a[m+1>>0]=J;q=q+-1|0;if(!q)break;else m=m+2|0}r=r+-1|0;if(!r)break;else{t=t+(s+D)|0;l=l+(s+z)|0}}}u=u+1|0}while((u|0)!=2);i=I;return}function Xb(b,c,e,f,g,h,j,k){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;r=i;i=i+448|0;l=r;if(((e|0)>=0?!((j+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)l=b;else{Ub(b,l,e,f,g,h,j,k+5|0,j);g=j;e=0;f=0}h=e+g+(Z(f,g)|0)|0;b=k>>>2;if(!b){i=r;return}n=g<<2;q=0-g|0;o=q<<1;p=g<<1;if(!j){i=r;return}else{m=l+h|0;e=l+(h+(g*5|0))|0}while(1){l=j;h=c;k=m;f=e;while(1){u=d[f+o>>0]|0;v=d[f+q>>0]|0;w=d[f+g>>0]|0;y=d[f>>0]|0;x=w+u|0;s=d[k+p>>0]|0;a[h+48>>0]=a[((d[f+p>>0]|0)+16-x-(x<<2)+s+((y+v|0)*20|0)>>5)+3984>>0]|0;x=s+y|0;t=d[k+g>>0]|0;a[h+32>>0]=a[(w+16-x-(x<<2)+t+((v+u|0)*20|0)>>5)+3984>>0]|0;x=t+v|0;w=d[k>>0]|0;a[h+16>>0]=a[(y+16-x-(x<<2)+w+((s+u|0)*20|0)>>5)+3984>>0]|0;u=w+u|0;a[h>>0]=a[(v+16-u-(u<<2)+(d[k+q>>0]|0)+((t+s|0)*20|0)>>5)+3984>>0]|0;l=l+-1|0;if(!l)break;else{h=h+1|0;k=k+1|0;f=f+1|0}}b=b+-1|0;if(!b)break;else{c=c+64|0;m=m+n|0;e=e+n|0}}i=r;return}function Yb(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;v=i;i=i+448|0;m=v;if(((e|0)>=0?!((j+e|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)m=b;else{Ub(b,m,e,f,g,h,j,k+5|0,j);g=j;e=0;f=0}h=e+g+(Z(f,g)|0)|0;b=k>>>2;if(!b){i=v;return}u=(j|0)==0;s=(g<<2)-j|0;t=64-j|0;r=0-g|0;p=r<<1;q=g<<1;e=m+h|0;f=m+(h+(Z(g,l+2|0)|0))|0;m=m+(h+(g*5|0))|0;while(1){if(u){h=c;k=f}else{k=f+j|0;h=c+j|0;l=j;o=e;n=m;while(1){y=d[n+p>>0]|0;z=d[n+r>>0]|0;A=d[n+g>>0]|0;C=d[n>>0]|0;B=A+y|0;w=d[o+q>>0]|0;a[c+48>>0]=((d[((d[n+q>>0]|0)+16-B-(B<<2)+w+((C+z|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+q>>0]|0)|0)>>>1;B=w+C|0;x=d[o+g>>0]|0;a[c+32>>0]=((d[(A+16-B-(B<<2)+x+((z+y|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+g>>0]|0)|0)>>>1;B=x+z|0;A=d[o>>0]|0;a[c+16>>0]=((d[(C+16-B-(B<<2)+A+((w+y|0)*20|0)>>5)+3984>>0]|0)+1+(d[f>>0]|0)|0)>>>1;y=A+y|0;a[c>>0]=((d[(z+16-y-(y<<2)+(d[o+r>>0]|0)+((x+w|0)*20|0)>>5)+3984>>0]|0)+1+(d[f+r>>0]|0)|0)>>>1;l=l+-1|0;if(!l)break;else{c=c+1|0;o=o+1|0;f=f+1|0;n=n+1|0}}e=e+j|0;m=m+j|0}b=b+-1|0;if(!b)break;else{c=h+t|0;e=e+s|0;f=k+s|0;m=m+s|0}}i=v;return}function Zb(b,c,e,f,g,h,j,k){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;u=i;i=i+448|0;l=u;if((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0|(k+f|0)>>>0>h>>>0):0)l=b;else{n=j+5|0;Ub(b,l,e,f,g,h,n,k,n);g=n;e=0;f=0}if(!k){i=u;return}r=j>>>2;t=(r|0)==0;s=g-j|0;q=16-j|0;p=r<<2;b=c;l=l+(e+5+(Z(f,g)|0))|0;o=k;while(1){if(t)h=b;else{h=b+p|0;e=l;g=d[l+-1>>0]|0;k=d[l+-2>>0]|0;m=d[l+-3>>0]|0;n=d[l+-4>>0]|0;j=d[l+-5>>0]|0;c=r;while(1){f=n+g|0;v=n;n=d[e>>0]|0;a[b>>0]=a[(j+16-f-(f<<2)+n+((m+k|0)*20|0)>>5)+3984>>0]|0;j=n+m|0;f=m;m=d[e+1>>0]|0;a[b+1>>0]=a[(v+16-j-(j<<2)+m+((k+g|0)*20|0)>>5)+3984>>0]|0;j=m+k|0;v=k;k=d[e+2>>0]|0;a[b+2>>0]=a[(f+16-j-(j<<2)+k+((n+g|0)*20|0)>>5)+3984>>0]|0;j=k+g|0;f=d[e+3>>0]|0;a[b+3>>0]=a[(v+16-j-(j<<2)+f+((m+n|0)*20|0)>>5)+3984>>0]|0;c=c+-1|0;if(!c)break;else{j=g;b=b+4|0;e=e+4|0;g=f}}l=l+p|0}o=o+-1|0;if(!o)break;else{b=h+q|0;l=l+s|0}}i=u;return}function _b(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;v=i;i=i+448|0;m=v;if((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0|(k+f|0)>>>0>h>>>0):0)m=b;else{o=j+5|0;Ub(b,m,e,f,g,h,o,k,o);g=o;e=0;f=0}if(!k){i=v;return}s=j>>>2;u=(s|0)==0;t=g-j|0;r=16-j|0;q=(l|0)!=0;p=s<<2;b=c;m=m+(e+5+(Z(f,g)|0))|0;while(1){if(u)h=b;else{h=b+p|0;l=m;e=d[m+-1>>0]|0;g=d[m+-2>>0]|0;n=d[m+-3>>0]|0;o=d[m+-4>>0]|0;j=d[m+-5>>0]|0;c=s;while(1){f=o+e|0;w=o;o=d[l>>0]|0;a[b>>0]=((q?g:n)+1+(d[(j+16-f-(f<<2)+o+((n+g|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=o+n|0;f=n;n=d[l+1>>0]|0;a[b+1>>0]=((q?e:g)+1+(d[(w+16-j-(j<<2)+n+((g+e|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=n+g|0;w=g;g=d[l+2>>0]|0;a[b+2>>0]=((q?o:e)+1+(d[(f+16-j-(j<<2)+g+((o+e|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;j=g+e|0;f=d[l+3>>0]|0;a[b+3>>0]=((q?n:o)+1+(d[(w+16-j-(j<<2)+f+((n+o|0)*20|0)>>5)+3984>>0]|0)|0)>>>1;c=c+-1|0;if(!c)break;else{j=e;b=b+4|0;l=l+4|0;e=f}}m=m+p|0}k=k+-1|0;if(!k)break;else{b=h+r|0;m=m+t|0}}i=v;return}function $b(b,c,e,f,g,h,j,k,l){b=b|0;c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;z=i;i=i+448|0;m=z;if(((e|0)>=0?!((e+5+j|0)>>>0>g>>>0|(f|0)<0):0)?(f+5+k|0)>>>0<=h>>>0:0)m=b;else{y=j+5|0;Ub(b,m,e,f,g,h,y,k+5|0,y);g=y;e=0;f=0}b=(Z(f,g)|0)+e|0;y=(l&1|2)+g+b|0;n=m+y|0;if(!k){i=z;return}u=j>>>2;w=(u|0)==0;v=g-j|0;x=16-j|0;t=u<<2;b=m+((Z(g,l>>>1&1|2)|0)+5+b)|0;s=k;while(1){if(!w){r=c+t|0;h=b;e=d[b+-1>>0]|0;f=d[b+-2>>0]|0;o=d[b+-3>>0]|0;p=d[b+-4>>0]|0;l=d[b+-5>>0]|0;q=u;while(1){A=p+e|0;B=p;p=d[h>>0]|0;a[c>>0]=a[(l+16-A-(A<<2)+p+((o+f|0)*20|0)>>5)+3984>>0]|0;A=p+o|0;l=o;o=d[h+1>>0]|0;a[c+1>>0]=a[(B+16-A-(A<<2)+o+((f+e|0)*20|0)>>5)+3984>>0]|0;A=o+f|0;B=f;f=d[h+2>>0]|0;a[c+2>>0]=a[(l+16-A-(A<<2)+f+((p+e|0)*20|0)>>5)+3984>>0]|0;A=f+e|0;l=d[h+3>>0]|0;a[c+3>>0]=a[(B+16-A-(A<<2)+l+((o+p|0)*20|0)>>5)+3984>>0]|0;q=q+-1|0;if(!q)break;else{A=e;c=c+4|0;h=h+4|0;e=l;l=A}}c=r;b=b+t|0}s=s+-1|0;if(!s)break;else{c=c+x|0;b=b+v|0}}b=k>>>2;if(!b){i=z;return}t=(j|0)==0;p=(g<<2)-j|0;o=64-j|0;q=0-g|0;s=q<<1;r=g<<1;c=c+(x-(k<<4))|0;h=m+(y+(g*5|0))|0;l=b;while(1){if(t){b=c;m=n}else{b=c+j|0;m=c;e=n;f=h;c=j;while(1){x=d[f+s>>0]|0;w=d[f+q>>0]|0;u=d[f+g>>0]|0;B=d[f>>0]|0;y=u+x|0;k=d[e+r>>0]|0;A=m+48|0;a[A>>0]=((d[((d[f+r>>0]|0)+16-y-(y<<2)+k+((B+w|0)*20|0)>>5)+3984>>0]|0)+1+(d[A>>0]|0)|0)>>>1;A=k+B|0;y=d[e+g>>0]|0;v=m+32|0;a[v>>0]=((d[(u+16-A-(A<<2)+y+((w+x|0)*20|0)>>5)+3984>>0]|0)+1+(d[v>>0]|0)|0)>>>1;v=d[e>>0]|0;A=y+w|0;u=m+16|0;a[u>>0]=((d[(B+16-A-(A<<2)+v+((k+x|0)*20|0)>>5)+3984>>0]|0)+1+(d[u>>0]|0)|0)>>>1;x=v+x|0;a[m>>0]=((d[(w+16-x-(x<<2)+(d[e+q>>0]|0)+((y+k|0)*20|0)>>5)+3984>>0]|0)+1+(d[m>>0]|0)|0)>>>1;c=c+-1|0;if(!c)break;else{m=m+1|0;e=e+1|0;f=f+1|0}}m=n+j|0;h=h+j|0}l=l+-1|0;if(!l)break;else{c=b+o|0;n=m+p|0;h=h+p|0}}i=z;return}function ac(b,e,f,g,h,j,k,l){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;x=i;i=i+1792|0;m=x+1344|0;w=x;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0){o=l+5|0;m=b;n=f+5|0}else{n=k+5|0;o=l+5|0;Ub(b,m,f,g,h,j,n,o,n);h=n;n=5;g=0}if(o){t=k>>>2;v=(t|0)==0;s=h-k|0;u=t<<2;f=w;m=m+(n+(Z(g,h)|0))|0;while(1){if(v)b=f;else{b=f+(u<<2)|0;g=m;h=d[m+-1>>0]|0;j=d[m+-2>>0]|0;p=d[m+-3>>0]|0;q=d[m+-4>>0]|0;n=d[m+-5>>0]|0;r=t;while(1){y=q+h|0;z=q;q=d[g>>0]|0;c[f>>2]=n-y-(y<<2)+q+((p+j|0)*20|0);y=q+p|0;n=p;p=d[g+1>>0]|0;c[f+4>>2]=z-y+p-(y<<2)+((j+h|0)*20|0);y=p+j|0;z=j;j=d[g+2>>0]|0;c[f+8>>2]=n-y+j-(y<<2)+((q+h|0)*20|0);y=j+h|0;n=d[g+3>>0]|0;c[f+12>>2]=z-y+n-(y<<2)+((p+q|0)*20|0);r=r+-1|0;if(!r)break;else{y=h;f=f+16|0;g=g+4|0;h=n;n=y}}m=m+u|0}o=o+-1|0;if(!o)break;else{f=b;m=m+s|0}}}h=l>>>2;if(!h){i=x;return}u=(k|0)==0;s=64-k|0;p=k*3|0;t=0-k|0;q=t<<1;r=k<<1;g=e;b=w+(k<<2)|0;m=w+(k*6<<2)|0;o=h;while(1){if(u)h=g;else{h=g+k|0;f=b;j=m;n=k;while(1){e=c[j+(q<<2)>>2]|0;w=c[j+(t<<2)>>2]|0;z=c[j+(k<<2)>>2]|0;A=c[j>>2]|0;y=z+e|0;v=c[f+(r<<2)>>2]|0;a[g+48>>0]=a[((c[j+(r<<2)>>2]|0)+512-y-(y<<2)+v+((A+w|0)*20|0)>>10)+3984>>0]|0;y=v+A|0;l=c[f+(k<<2)>>2]|0;a[g+32>>0]=a[(z+512-y-(y<<2)+l+((w+e|0)*20|0)>>10)+3984>>0]|0;y=c[f>>2]|0;z=l+w|0;a[g+16>>0]=a[(A+512-z-(z<<2)+y+((v+e|0)*20|0)>>10)+3984>>0]|0;e=y+e|0;a[g>>0]=a[(w+512-e-(e<<2)+(c[f+(t<<2)>>2]|0)+((l+v|0)*20|0)>>10)+3984>>0]|0;n=n+-1|0;if(!n)break;else{g=g+1|0;f=f+4|0;j=j+4|0}}b=b+(k<<2)|0;m=m+(k<<2)|0}o=o+-1|0;if(!o)break;else{g=h+s|0;b=b+(p<<2)|0;m=m+(p<<2)|0}}i=x;return}function bc(b,e,f,g,h,j,k,l,m){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;y=i;i=i+1792|0;n=y+1344|0;x=y;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0){o=l+5|0;n=b;f=f+5|0}else{q=k+5|0;o=l+5|0;Ub(b,n,f,g,h,j,q,o,q);h=q;f=5;g=0}if(o){v=k>>>2;t=(v|0)==0;u=h-k|0;w=v<<2;p=x;n=n+(f+(Z(g,h)|0))|0;s=o;while(1){if(t)b=p;else{b=p+(w<<2)|0;g=n;f=d[n+-1>>0]|0;h=d[n+-2>>0]|0;j=d[n+-3>>0]|0;q=d[n+-4>>0]|0;o=d[n+-5>>0]|0;r=v;while(1){z=q+f|0;A=q;q=d[g>>0]|0;c[p>>2]=o-z-(z<<2)+q+((j+h|0)*20|0);z=q+j|0;o=j;j=d[g+1>>0]|0;c[p+4>>2]=A-z+j-(z<<2)+((h+f|0)*20|0);z=j+h|0;A=h;h=d[g+2>>0]|0;c[p+8>>2]=o-z+h-(z<<2)+((q+f|0)*20|0);z=h+f|0;o=d[g+3>>0]|0;c[p+12>>2]=A-z+o-(z<<2)+((j+q|0)*20|0);r=r+-1|0;if(!r)break;else{z=f;p=p+16|0;g=g+4|0;f=o;o=z}}n=n+w|0}s=s+-1|0;if(!s)break;else{p=b;n=n+u|0}}}f=l>>>2;if(!f){i=y;return}w=(k|0)==0;u=64-k|0;q=k*3|0;v=0-k|0;t=v<<1;s=k<<1;b=x+(k<<2)|0;n=x+((Z(m+2|0,k)|0)+k<<2)|0;h=x+(k*6<<2)|0;r=f;while(1){if(w){g=e;f=n}else{f=n+(k<<2)|0;g=e+k|0;p=b;j=h;o=k;while(1){m=c[j+(t<<2)>>2]|0;l=c[j+(v<<2)>>2]|0;B=c[j+(k<<2)>>2]|0;C=c[j>>2]|0;A=B+m|0;z=c[p+(s<<2)>>2]|0;a[e+48>>0]=((d[((c[j+(s<<2)>>2]|0)+512-A-(A<<2)+z+((C+l|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(s<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;A=z+C|0;x=c[p+(k<<2)>>2]|0;a[e+32>>0]=((d[(B+512-A-(A<<2)+x+((l+m|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(k<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;A=c[p>>2]|0;B=x+l|0;a[e+16>>0]=((d[(C+512-B-(B<<2)+A+((z+m|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=A+m|0;a[e>>0]=((d[(l+512-m-(m<<2)+(c[p+(v<<2)>>2]|0)+((x+z|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[n+(v<<2)>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;o=o+-1|0;if(!o)break;else{e=e+1|0;p=p+4|0;n=n+4|0;j=j+4|0}}b=b+(k<<2)|0;h=h+(k<<2)|0}r=r+-1|0;if(!r)break;else{e=g+u|0;b=b+(q<<2)|0;n=f+(q<<2)|0;h=h+(q<<2)|0}}i=y;return}function cc(b,e,f,g,h,j,k,l,m){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;B=i;i=i+1792|0;n=B+1344|0;A=B;z=k+5|0;if(((f|0)>=0?!((f+5+k|0)>>>0>h>>>0|(g|0)<0):0)?(g+5+l|0)>>>0<=j>>>0:0)n=b;else{Ub(b,n,f,g,h,j,z,l+5|0,z);h=z;f=0;g=0}s=f+h+(Z(g,h)|0)|0;g=l>>>2;if(g){y=(z|0)==0;x=(h<<2)-k+-5|0;t=z*3|0;p=0-h|0;w=p<<1;v=h<<1;u=z<<1;q=-5-k|0;j=A+(z<<2)|0;r=n+s|0;f=n+(s+(h*5|0))|0;while(1){if(y)s=j;else{s=j+(z<<2)|0;n=r;b=f;o=z;while(1){E=d[b+w>>0]|0;F=d[b+p>>0]|0;H=d[b+h>>0]|0;I=d[b>>0]|0;G=H+E|0;C=d[n+v>>0]|0;c[j+(u<<2)>>2]=(d[b+v>>0]|0)-G-(G<<2)+C+((I+F|0)*20|0);G=C+I|0;D=d[n+h>>0]|0;c[j+(z<<2)>>2]=H-G+D-(G<<2)+((F+E|0)*20|0);G=d[n>>0]|0;H=D+F|0;c[j>>2]=I-H+G-(H<<2)+((C+E|0)*20|0);E=G+E|0;c[j+(q<<2)>>2]=F-E+(d[n+p>>0]|0)-(E<<2)+((D+C|0)*20|0);o=o+-1|0;if(!o)break;else{j=j+4|0;n=n+1|0;b=b+1|0}}r=r+z|0;f=f+z|0}g=g+-1|0;if(!g)break;else{j=s+(t<<2)|0;r=r+x|0;f=f+x|0}}}if(!l){i=B;return}v=k>>>2;w=(v|0)==0;u=16-k|0;t=v<<2;h=A+(m+2<<2)|0;g=A+20|0;while(1){if(w)f=h;else{f=h+(t<<2)|0;s=e;n=g;j=c[g+-4>>2]|0;o=c[g+-8>>2]|0;p=c[g+-12>>2]|0;q=c[g+-16>>2]|0;b=c[g+-20>>2]|0;r=v;while(1){m=q+j|0;k=q;q=c[n>>2]|0;a[s>>0]=((d[(b+512-m-(m<<2)+q+((p+o|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=q+p|0;b=p;p=c[n+4>>2]|0;a[s+1>>0]=((d[(k+512-m-(m<<2)+p+((o+j|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+4>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=p+o|0;k=o;o=c[n+8>>2]|0;a[s+2>>0]=((d[(b+512-m-(m<<2)+o+((q+j|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+8>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;m=o+j|0;b=c[n+12>>2]|0;a[s+3>>0]=((d[(k+512-m-(m<<2)+b+((p+q|0)*20|0)>>10)+3984>>0]|0)+1+(d[((c[h+12>>2]|0)+16>>5)+3984>>0]|0)|0)>>>1;r=r+-1|0;if(!r)break;else{m=j;s=s+4|0;h=h+16|0;n=n+16|0;j=b;b=m}}e=e+t|0;g=g+(t<<2)|0}l=l+-1|0;if(!l)break;else{e=e+u|0;h=f+20|0;g=g+20|0}}i=B;return}function dc(a,d,e,f,g,h,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;x=i;q=a+((j<<4)+h)|0;u=b[d>>1]|0;w=d+2|0;t=b[w>>1]|0;s=e+4|0;p=c[s>>2]<<4;r=e+8|0;o=c[r>>2]<<4;f=h+f|0;m=f+(u>>2)|0;g=j+g|0;n=g+(t>>2)|0;do switch(c[6800+((u&3)<<4)+((t&3)<<2)>>2]|0){case 10:{ac(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l);break}case 6:{cc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 4:{_b(c[e>>2]|0,q,m+-2|0,n,p,o,k,l,0);break}case 1:{Yb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l,0);break}case 2:{Xb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l);break}case 12:{_b(c[e>>2]|0,q,m+-2|0,n,p,o,k,l,1);break}case 14:{cc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}case 7:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,2);break}case 13:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}case 5:{$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 0:{Ub(c[e>>2]|0,q,m,n,p,o,k,l,16);break}case 9:{bc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,0);break}case 8:{Zb(c[e>>2]|0,q,m+-2|0,n,p,o,k,l);break}case 3:{Yb(c[e>>2]|0,q,m,n+-2|0,p,o,k,l,1);break}case 11:{bc(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,1);break}default:$b(c[e>>2]|0,q,m+-2|0,n+-2|0,p,o,k,l,3)}while(0);u=(h>>>1)+256+(j>>>1<<3)|0;v=a+u|0;t=c[e>>2]|0;m=c[s>>2]|0;j=c[r>>2]|0;r=m<<3;s=j<<3;p=b[d>>1]|0;e=(p>>3)+(f>>>1)|0;q=b[w>>1]|0;o=(q>>3)+(g>>>1)|0;p=p&7;q=q&7;g=k>>>1;h=l>>>1;j=Z(m<<8,j)|0;f=t+j|0;m=(p|0)!=0;n=(q|0)!=0;if(m&n){Wb(f,v,e,o,r,s,p,q,g,h);i=x;return}if(m){Tb(f,v,e,o,r,s,p,g,h);i=x;return}if(n){Vb(f,v,e,o,r,s,q,g,h);i=x;return}else{Ub(f,v,e,o,r,s,g,h,8);Ub(t+((Z(s,r)|0)+j)|0,a+(u+64)|0,e,o,r,s,g,h,8);i=x;return}}function ec(b,c,d,e,f){b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0;j=i;if(d){nd(c|0,a[b>>0]|0,d|0)|0;c=c+d|0}if(e){h=c+e|0;g=e;d=b;while(1){a[c>>0]=a[d>>0]|0;g=g+-1|0;if(!g)break;else{c=c+1|0;d=d+1|0}}c=h;b=b+e|0}if(!f){i=j;return}nd(c|0,a[b+-1>>0]|0,f|0)|0;i=j;return}function fc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;c=i;hd(b,a,d);i=c;return}function gc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;f=c[a+40>>2]|0;if(f){h=c[a>>2]|0;k=a+32|0;j=0;do{if(((c[h+(j*40|0)+20>>2]|0)+-1|0)>>>0<2){g=c[h+(j*40|0)+12>>2]|0;if(g>>>0>d>>>0)g=g-(c[k>>2]|0)|0;c[h+(j*40|0)+8>>2]=g}j=j+1|0}while((j|0)!=(f|0))}if(!(c[b>>2]|0)){p=0;i=q;return p|0}g=c[b+4>>2]|0;if(g>>>0>=3){p=0;i=q;return p|0}o=a+32|0;p=a+24|0;n=a+4|0;f=d;m=0;a:while(1){b:do if(g>>>0<2){k=c[b+(m*12|0)+8>>2]|0;if(!g){g=f-k|0;if((g|0)<0)g=(c[o>>2]|0)+g|0}else{l=k+f|0;g=c[o>>2]|0;g=l-((l|0)<(g|0)?0:g)|0}if(g>>>0>d>>>0)f=g-(c[o>>2]|0)|0;else f=g;j=c[p>>2]|0;if(!j){f=1;g=37;break a}k=c[a>>2]|0;l=0;while(1){h=c[k+(l*40|0)+20>>2]|0;if((h+-1|0)>>>0<2?(c[k+(l*40|0)+8>>2]|0)==(f|0):0){f=g;break b}l=l+1|0;if(l>>>0>=j>>>0){f=1;g=37;break a}}}else{j=c[b+(m*12|0)+12>>2]|0;h=c[p>>2]|0;if(!h){f=1;g=37;break a}k=c[a>>2]|0;g=0;while(1){if((c[k+(g*40|0)+20>>2]|0)==3?(c[k+(g*40|0)+8>>2]|0)==(j|0):0){h=3;l=g;break b}g=g+1|0;if(g>>>0>=h>>>0){f=1;g=37;break a}}}while(0);if(!((l|0)>-1&h>>>0>1)){f=1;g=37;break}if(m>>>0>>0){k=e;do{j=k;k=k+-1|0;h=c[n>>2]|0;c[h+(j<<2)>>2]=c[h+(k<<2)>>2]}while(k>>>0>m>>>0);k=c[a>>2]|0}c[(c[n>>2]|0)+(m<<2)>>2]=k+(l*40|0);m=m+1|0;if(m>>>0<=e>>>0){g=m;k=m;do{j=c[n>>2]|0;h=c[j+(g<<2)>>2]|0;if((h|0)!=((c[a>>2]|0)+(l*40|0)|0)){c[j+(k<<2)>>2]=h;k=k+1|0}g=g+1|0}while(g>>>0<=e>>>0)}g=c[b+(m*12|0)+4>>2]|0;if(g>>>0>=3){f=0;g=37;break}}if((g|0)==37){i=q;return f|0}return 0}function hc(a,b,d,e,f,g,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0;K=i;I=c[d>>2]|0;J=c[a+8>>2]|0;if((I|0)!=(c[J>>2]|0)){D=1;i=K;return D|0}B=a+52|0;c[B>>2]=0;G=c[a+56>>2]|0;o=(G|0)==0;H=o&1;do if(!b){c[J+20>>2]=0;c[J+12>>2]=e;c[J+8>>2]=e;c[J+16>>2]=f;c[J+24>>2]=H;if(o){d=a+44|0;c[d>>2]=(c[d>>2]|0)+1;d=0;r=0}else{d=G;r=0}}else{if(g){k=a+20|0;c[k>>2]=0;l=a+16|0;c[l>>2]=0;r=c[a>>2]|0;s=a+44|0;q=0;do{p=r+(q*40|0)+20|0;if((c[p>>2]|0)!=0?(c[p>>2]=0,(c[r+(q*40|0)+24>>2]|0)==0):0)c[s>>2]=(c[s>>2]|0)+-1;q=q+1|0}while((q|0)!=16);a:do if(o){n=c[a+28>>2]|0;m=a+12|0;q=0;while(1){e=0;p=2147483647;o=0;do{if(c[r+(e*40|0)+24>>2]|0){C=c[r+(e*40|0)+16>>2]|0;D=(C|0)<(p|0);p=D?C:p;o=D?r+(e*40|0)|0:o}e=e+1|0}while(e>>>0<=n>>>0);if(!o){d=0;break a}D=c[m>>2]|0;c[D+(q<<4)>>2]=c[o>>2];c[D+(q<<4)+12>>2]=c[o+36>>2];c[D+(q<<4)+4>>2]=c[o+28>>2];c[D+(q<<4)+8>>2]=c[o+32>>2];q=q+1|0;c[l>>2]=q;c[o+24>>2]=0;if(c[o+20>>2]|0)continue;c[s>>2]=(c[s>>2]|0)+-1}}else d=G;while(0);p=a+40|0;c[p>>2]=0;o=a+36|0;c[o>>2]=65535;c[a+48>>2]=0;if(!(c[b>>2]|d))d=0;else{c[l>>2]=0;c[k>>2]=0}r=(c[b+4>>2]|0)==0;c[J+20>>2]=r?2:3;c[o>>2]=r?65535:0;c[J+12>>2]=0;c[J+8>>2]=0;c[J+16>>2]=0;c[J+24>>2]=H;c[s>>2]=1;c[p>>2]=1;r=0;break}if(!(c[b+8>>2]|0)){d=a+40|0;q=c[d>>2]|0;p=c[a+24>>2]|0;if(q>>>0>=p>>>0)if(q){l=c[a>>2]|0;m=0;o=-1;n=0;do{if(((c[l+(m*40|0)+20>>2]|0)+-1|0)>>>0<2){D=c[l+(m*40|0)+8>>2]|0;C=(D|0)<(n|0)|(o|0)==-1;o=C?m:o;n=C?D:n}m=m+1|0}while((m|0)!=(q|0));if((o|0)>-1){q=q+-1|0;c[l+(o*40|0)+20>>2]=0;c[d>>2]=q;if(!(c[l+(o*40|0)+24>>2]|0)){d=a+44|0;c[d>>2]=(c[d>>2]|0)+-1;d=G;n=0}else{d=G;n=0}}else{d=G;n=1}}else{q=0;d=G;n=1}else{d=G;n=0}}else{E=a+24|0;C=a+40|0;v=a+44|0;x=a+36|0;A=a+48|0;u=a+28|0;y=a+16|0;z=a+12|0;r=G;d=G;t=0;w=0;b:while(1){switch(c[b+(t*20|0)+12>>2]|0){case 4:{l=c[b+(t*20|0)+28>>2]|0;c[x>>2]=l;m=c[E>>2]|0;if(!m)s=w;else{n=c[a>>2]|0;s=l;o=0;do{k=n+(o*40|0)+20|0;do if((c[k>>2]|0)==3){if((c[n+(o*40|0)+8>>2]|0)>>>0<=l>>>0)if((s|0)==65535)s=65535;else break;c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[n+(o*40|0)+24>>2]|0))c[v>>2]=(c[v>>2]|0)+-1}while(0);o=o+1|0}while((o|0)!=(m|0));s=w}break}case 1:{n=e-(c[b+(t*20|0)+16>>2]|0)|0;l=c[E>>2]|0;if(!l){n=1;break b}m=c[a>>2]|0;s=0;while(1){k=m+(s*40|0)+20|0;if(((c[k>>2]|0)+-1|0)>>>0<2?(c[m+(s*40|0)+8>>2]|0)==(n|0):0)break;s=s+1|0;if(s>>>0>=l>>>0){n=1;break b}}if((s|0)<0){n=1;break b}c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[m+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=w}else s=w;break}case 6:{m=c[b+(t*20|0)+24>>2]|0;s=c[x>>2]|0;if((s|0)==65535|s>>>0>>0){n=1;F=101;break b}r=c[E>>2]|0;c:do if(r){l=c[a>>2]|0;s=0;while(1){k=l+(s*40|0)+20|0;if((c[k>>2]|0)==3?(c[l+(s*40|0)+8>>2]|0)==(m|0):0)break;s=s+1|0;if(s>>>0>=r>>>0){F=88;break c}}c[k>>2]=0;k=(c[C>>2]|0)+-1|0;c[C>>2]=k;if(!(c[l+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=k}else s=k}else{r=0;F=88}while(0);if((F|0)==88){F=0;s=c[C>>2]|0}if(s>>>0>=r>>>0){n=1;F=101;break b}c[J+12>>2]=e;c[J+8>>2]=m;c[J+16>>2]=f;c[J+20>>2]=3;c[J+24>>2]=H;c[C>>2]=s+1;c[v>>2]=(c[v>>2]|0)+1;r=G;d=G;s=1;break}case 2:{l=c[b+(t*20|0)+20>>2]|0;m=c[E>>2]|0;if(!m){n=1;break b}n=c[a>>2]|0;s=0;while(1){k=n+(s*40|0)+20|0;if((c[k>>2]|0)==3?(c[n+(s*40|0)+8>>2]|0)==(l|0):0)break;s=s+1|0;if(s>>>0>=m>>>0){n=1;break b}}if((s|0)<0){n=1;break b}c[k>>2]=0;c[C>>2]=(c[C>>2]|0)+-1;if(!(c[n+(s*40|0)+24>>2]|0)){c[v>>2]=(c[v>>2]|0)+-1;s=w}else s=w;break}case 3:{s=c[b+(t*20|0)+16>>2]|0;n=c[b+(t*20|0)+24>>2]|0;k=c[x>>2]|0;if((k|0)==65535|k>>>0>>0){n=1;break b}o=c[E>>2]|0;if(!o){n=1;break b}p=c[a>>2]|0;k=0;while(1){m=p+(k*40|0)+20|0;if((c[m>>2]|0)==3?(c[p+(k*40|0)+8>>2]|0)==(n|0):0){F=47;break}l=k+1|0;if(l>>>0>>0)k=l;else break}if((F|0)==47?(F=0,c[m>>2]=0,c[C>>2]=(c[C>>2]|0)+-1,(c[p+(k*40|0)+24>>2]|0)==0):0)c[v>>2]=(c[v>>2]|0)+-1;m=e-s|0;s=0;while(1){l=p+(s*40|0)+20|0;k=c[l>>2]|0;if((k+-1|0)>>>0<2?(D=p+(s*40|0)+8|0,(c[D>>2]|0)==(m|0)):0)break;s=s+1|0;if(s>>>0>=o>>>0){n=1;break b}}if(!((s|0)>-1&k>>>0>1)){n=1;break b}c[l>>2]=3;c[D>>2]=n;s=w;break}case 5:{n=c[a>>2]|0;q=0;do{p=n+(q*40|0)+20|0;if((c[p>>2]|0)!=0?(c[p>>2]=0,(c[n+(q*40|0)+24>>2]|0)==0):0)c[v>>2]=(c[v>>2]|0)+-1;q=q+1|0}while((q|0)!=16);d:do if(!d){l=c[u>>2]|0;m=r;while(1){d=0;s=2147483647;k=0;do{if(c[n+(d*40|0)+24>>2]|0){o=c[n+(d*40|0)+16>>2]|0;e=(o|0)<(s|0);s=e?o:s;k=e?n+(d*40|0)|0:k}d=d+1|0}while(d>>>0<=l>>>0);if(!k){r=m;d=0;break d}s=c[y>>2]|0;d=c[z>>2]|0;c[d+(s<<4)>>2]=c[k>>2];c[d+(s<<4)+12>>2]=c[k+36>>2];c[d+(s<<4)+4>>2]=c[k+28>>2];c[d+(s<<4)+8>>2]=c[k+32>>2];c[y>>2]=s+1;c[k+24>>2]=0;if(!(c[k+20>>2]|0))c[v>>2]=(c[v>>2]|0)+-1;if(!m)m=0;else{r=m;d=m;break}}}while(0);c[C>>2]=0;c[x>>2]=65535;c[A>>2]=0;c[B>>2]=1;e=0;s=w;break}case 0:{n=0;F=101;break b}default:{n=1;break b}}t=t+1|0;w=s}if(w){r=n;break}q=c[C>>2]|0;p=c[E>>2]|0}if(q>>>0

>>0){c[J+12>>2]=e;c[J+8>>2]=e;c[J+16>>2]=f;c[J+20>>2]=2;c[J+24>>2]=H;r=a+44|0;c[r>>2]=(c[r>>2]|0)+1;c[a+40>>2]=q+1;r=n}else r=1}while(0);c[J+36>>2]=g;c[J+28>>2]=h;c[J+32>>2]=j;if(!d){o=a+44|0;d=c[o>>2]|0;k=c[a+28>>2]|0;if(d>>>0>k>>>0){p=a+16|0;q=a+12|0;do{n=c[a>>2]|0;e=0;l=2147483647;m=0;do{if(c[n+(e*40|0)+24>>2]|0){C=c[n+(e*40|0)+16>>2]|0;D=(C|0)<(l|0);l=D?C:l;m=D?n+(e*40|0)|0:m}e=e+1|0}while(e>>>0<=k>>>0);if((m|0)!=0?(D=c[p>>2]|0,C=c[q>>2]|0,c[C+(D<<4)>>2]=c[m>>2],c[C+(D<<4)+12>>2]=c[m+36>>2],c[C+(D<<4)+4>>2]=c[m+28>>2],c[C+(D<<4)+8>>2]=c[m+32>>2],c[p>>2]=D+1,c[m+24>>2]=0,(c[m+20>>2]|0)==0):0){d=d+-1|0;c[o>>2]=d}}while(d>>>0>k>>>0)}}else{k=a+16|0;D=c[k>>2]|0;C=c[a+12>>2]|0;c[C+(D<<4)>>2]=I;c[C+(D<<4)+12>>2]=g;c[C+(D<<4)+4>>2]=h;c[C+(D<<4)+8>>2]=j;c[k>>2]=D+1;k=c[a+28>>2]|0}rc(c[a>>2]|0,k+1|0);D=r;i=K;return D|0}function ic(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;if((b>>>0<=16?(d=c[(c[a+4>>2]|0)+(b<<2)>>2]|0,(d|0)!=0):0)?(c[d+20>>2]|0)>>>0>1:0)d=c[d>>2]|0;else d=0;i=e;return d|0}function jc(a){a=a|0;var b=0;b=(c[a>>2]|0)+((c[a+28>>2]|0)*40|0)|0;c[a+8>>2]=b;return c[b>>2]|0}function kc(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0;j=i;c[a+36>>2]=65535;e=e>>>0>1?e:1;c[a+24>>2]=e;h=a+28|0;c[h>>2]=(g|0)==0?d:e;c[a+32>>2]=f;c[a+56>>2]=g;c[a+44>>2]=0;c[a+40>>2]=0;c[a+48>>2]=0;g=fd(680)|0;c[a>>2]=g;if(!g){g=65535;i=j;return g|0}id(g,0,680);a:do if((c[h>>2]|0)!=-1){f=b*384|47;e=0;while(1){d=fd(f)|0;g=c[a>>2]|0;c[g+(e*40|0)+4>>2]=d;if(!d){g=65535;break}c[g+(e*40|0)>>2]=d+(0-d&15);e=e+1|0;if(e>>>0>=((c[h>>2]|0)+1|0)>>>0)break a}i=j;return g|0}while(0);g=a+4|0;c[g>>2]=fd(68)|0;f=fd((c[h>>2]<<4)+16|0)|0;c[a+12>>2]=f;g=c[g>>2]|0;if((g|0)==0|(f|0)==0){g=65535;i=j;return g|0}id(g,0,68);c[a+20>>2]=0;c[a+16>>2]=0;g=0;i=j;return g|0}function lc(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0;l=i;h=c[a>>2]|0;if(h){k=a+28|0;if((c[k>>2]|0)!=-1){j=0;do{gd(c[h+(j*40|0)+4>>2]|0);h=c[a>>2]|0;c[h+(j*40|0)+4>>2]=0;j=j+1|0}while(j>>>0<((c[k>>2]|0)+1|0)>>>0)}}else h=0;gd(h);c[a>>2]=0;h=a+4|0;gd(c[h>>2]|0);c[h>>2]=0;h=a+12|0;gd(c[h>>2]|0);c[h>>2]=0;h=kc(a,b,d,e,f,g)|0;i=l;return h|0}function mc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;b=c[a>>2]|0;if(b){e=a+28|0;if((c[e>>2]|0)!=-1){d=0;do{gd(c[b+(d*40|0)+4>>2]|0);b=c[a>>2]|0;c[b+(d*40|0)+4>>2]=0;d=d+1|0}while(d>>>0<((c[e>>2]|0)+1|0)>>>0)}}else b=0;gd(b);c[a>>2]=0;b=a+4|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+12|0;gd(c[b>>2]|0);c[b>>2]=0;i=f;return}function nc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;b=c[a+40>>2]|0;if(!b){i=f;return}e=a+4|0;d=0;do{c[(c[e>>2]|0)+(d<<2)>>2]=(c[a>>2]|0)+(d*40|0);d=d+1|0}while(d>>>0>>0);i=f;return}function oc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;y=i;v=a+16|0;c[v>>2]=0;c[a+20>>2]=0;if(!e){b=0;i=y;return b|0}x=a+48|0;e=c[x>>2]|0;f=(e|0)==(b|0);a:do if(!f?(u=a+32|0,l=c[u>>2]|0,k=((e+1|0)>>>0)%(l>>>0)|0,(k|0)!=(b|0)):0){t=a+28|0;w=c[(c[a>>2]|0)+((c[t>>2]|0)*40|0)>>2]|0;r=a+40|0;p=a+24|0;o=a+44|0;q=a+56|0;s=a+12|0;n=k;while(1){k=c[r>>2]|0;if(!k)k=0;else{j=c[a>>2]|0;h=0;do{if(((c[j+(h*40|0)+20>>2]|0)+-1|0)>>>0<2){e=c[j+(h*40|0)+12>>2]|0;c[j+(h*40|0)+8>>2]=e-(e>>>0>n>>>0?l:0)}h=h+1|0}while((h|0)!=(k|0))}if(k>>>0>=(c[p>>2]|0)>>>0){if(!k){e=1;g=46;break}f=c[a>>2]|0;h=0;l=-1;j=0;while(1){if(((c[f+(h*40|0)+20>>2]|0)+-1|0)>>>0<2){e=c[f+(h*40|0)+8>>2]|0;m=(e|0)<(j|0)|(l|0)==-1;g=m?h:l;j=m?e:j}else g=l;h=h+1|0;if((h|0)==(k|0))break;else l=g}if((g|0)<=-1){e=1;g=46;break}l=k+-1|0;c[f+(g*40|0)+20>>2]=0;c[r>>2]=l;if(!(c[f+(g*40|0)+24>>2]|0)){c[o>>2]=(c[o>>2]|0)+-1;k=l}else k=l}l=c[o>>2]|0;m=c[t>>2]|0;if(l>>>0>=m>>>0){e=(c[q>>2]|0)==0;do if(e){g=c[a>>2]|0;f=0;j=2147483647;h=0;do{if(c[g+(f*40|0)+24>>2]|0){A=c[g+(f*40|0)+16>>2]|0;z=(A|0)<(j|0);j=z?A:j;h=z?g+(f*40|0)|0:h}f=f+1|0}while(f>>>0<=m>>>0);if((h|0)!=0?(f=c[v>>2]|0,g=c[s>>2]|0,c[g+(f<<4)>>2]=c[h>>2],c[g+(f<<4)+12>>2]=c[h+36>>2],c[g+(f<<4)+4>>2]=c[h+28>>2],c[g+(f<<4)+8>>2]=c[h+32>>2],c[v>>2]=f+1,c[h+24>>2]=0,(c[h+20>>2]|0)==0):0){l=l+-1|0;c[o>>2]=l}}while(l>>>0>=m>>>0)}e=c[a>>2]|0;c[e+(m*40|0)+20>>2]=1;c[e+(m*40|0)+12>>2]=n;c[e+(m*40|0)+8>>2]=n;c[e+(m*40|0)+16>>2]=0;c[e+(m*40|0)+24>>2]=0;c[o>>2]=l+1;c[r>>2]=k+1;rc(e,m+1|0);l=c[u>>2]|0;n=((n+1|0)>>>0)%(l>>>0)|0;if((n|0)==(b|0)){g=31;break}}if((g|0)==31){g=c[v>>2]|0;if(!g){g=41;break}e=c[s>>2]|0;h=c[t>>2]|0;j=c[a>>2]|0;l=j+(h*40|0)|0;k=c[l>>2]|0;f=0;while(1){if((c[e+(f<<4)>>2]|0)==(k|0))break;f=f+1|0;if(f>>>0>=g>>>0){g=41;break a}}if(!h){g=41;break}else e=0;while(1){f=j+(e*40|0)|0;e=e+1|0;if((c[f>>2]|0)==(w|0))break;if(e>>>0>=h>>>0){g=41;break a}}c[f>>2]=k;c[l>>2]=w;g=41;break}else if((g|0)==46){i=y;return e|0}}else g=39;while(0);if((g|0)==39)if(d)if(f){b=1;i=y;return b|0}else g=41;do if((g|0)==41){if(!d){e=c[x>>2]|0;break}c[x>>2]=b;b=0;i=y;return b|0}while(0);if((e|0)==(b|0)){b=0;i=y;return b|0}a=c[a+32>>2]|0;c[x>>2]=((b+-1+a|0)>>>0)%(a>>>0)|0;b=0;i=y;return b|0}function pc(a){a=a|0;var b=0,d=0,e=0;e=i;d=a+20|0;b=c[d>>2]|0;if(b>>>0>=(c[a+16>>2]|0)>>>0){b=0;i=e;return b|0}a=c[a+12>>2]|0;c[d>>2]=b+1;b=a+(b<<4)|0;i=e;return b|0}function qc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;k=i;f=c[a>>2]|0;if(!f){i=k;return}c[a+60>>2]=1;if(c[a+56>>2]|0){i=k;return}g=c[a+28>>2]|0;h=a+16|0;j=a+12|0;e=a+44|0;a=0;b=2147483647;d=0;while(1){if(c[f+(a*40|0)+24>>2]|0){m=c[f+(a*40|0)+16>>2]|0;l=(m|0)<(b|0);b=l?m:b;d=l?f+(a*40|0)|0:d}a=a+1|0;if(a>>>0<=g>>>0)continue;if(!d)break;l=c[h>>2]|0;b=c[j>>2]|0;c[b+(l<<4)>>2]=c[d>>2];c[b+(l<<4)+12>>2]=c[d+36>>2];c[b+(l<<4)+4>>2]=c[d+28>>2];c[b+(l<<4)+8>>2]=c[d+32>>2];c[h>>2]=l+1;c[d+24>>2]=0;if(c[d+20>>2]|0){a=0;b=2147483647;d=0;continue}c[e>>2]=(c[e>>2]|0)+-1;a=0;b=2147483647;d=0}i=k;return}function rc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=i;i=i+32|0;q=v+16|0;t=v;o=7;do{if(o>>>0>>0){n=o;do{m=a+(n*40|0)|0;l=c[m>>2]|0;m=c[m+4>>2]|0;p=c[a+(n*40|0)+8>>2]|0;k=a+(n*40|0)+12|0;s=c[k+4>>2]|0;r=q;c[r>>2]=c[k>>2];c[r+4>>2]=s;r=c[a+(n*40|0)+20>>2]|0;s=c[a+(n*40|0)+24>>2]|0;k=a+(n*40|0)+28|0;c[t+0>>2]=c[k+0>>2];c[t+4>>2]=c[k+4>>2];c[t+8>>2]=c[k+8>>2];a:do if(n>>>0>>0){d=n;u=8}else{f=(s|0)==0;j=r+-1|0;k=j>>>0<2;b:do if(!r){e=n;while(1){d=e-o|0;if(c[a+(d*40|0)+20>>2]|0){d=e;break b}if((c[a+(d*40|0)+24>>2]|0)!=0|f){d=e;break b}e=a+(e*40|0)+0|0;g=a+(d*40|0)+0|0;h=e+40|0;do{c[e>>2]=c[g>>2];e=e+4|0;g=g+4|0}while((e|0)<(h|0));if(d>>>0>>0){u=8;break a}else e=d}}else{d=n;while(1){f=d-o|0;e=c[a+(f*40|0)+20>>2]|0;do if(e){e=e+-1|0;if((e|j)>>>0<2){e=c[a+(f*40|0)+8>>2]|0;if((e|0)>(p|0))break b;d=a+(d*40|0)|0;if((e|0)<(p|0))break;else break a}if(e>>>0<2)break b;if(!k?(c[a+(f*40|0)+8>>2]|0)<=(p|0):0)break b;else u=16}else u=16;while(0);if((u|0)==16){u=0;d=a+(d*40|0)|0}e=d+0|0;g=a+(f*40|0)+0|0;h=e+40|0;do{c[e>>2]=c[g>>2];e=e+4|0;g=g+4|0}while((e|0)<(h|0));if(f>>>0>>0){d=f;u=8;break a}else d=f}}while(0);d=a+(d*40|0)|0}while(0);if((u|0)==8){u=0;d=a+(d*40|0)|0}k=d;c[k>>2]=l;c[k+4>>2]=m;c[d+8>>2]=p;k=q;l=c[k+4>>2]|0;m=d+12|0;c[m>>2]=c[k>>2];c[m+4>>2]=l;c[d+20>>2]=r;c[d+24>>2]=s;m=d+28|0;c[m+0>>2]=c[t+0>>2];c[m+4>>2]=c[t+4>>2];c[m+8>>2]=c[t+8>>2];n=n+1|0}while((n|0)!=(b|0))}o=o>>>1}while((o|0)!=0);i=v;return}function sc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;e=c[a+4>>2]|0;f=c[a+16>>2]|0;g=c[a+20>>2]|0;j=e<<2;k=b+256|0;h=16;a=c[a+12>>2]|0;d=b;while(1){m=c[d+4>>2]|0;c[a>>2]=c[d>>2];c[a+4>>2]=m;m=c[d+12>>2]|0;c[a+8>>2]=c[d+8>>2];c[a+12>>2]=m;h=h+-1|0;if(!h)break;else{a=a+(j<<2)|0;d=d+16|0}}j=e<<1&2147483646;h=c[b+260>>2]|0;c[f>>2]=c[k>>2];c[f+4>>2]=h;k=c[b+268>>2]|0;c[f+(j<<2)>>2]=c[b+264>>2];c[f+((j|1)<<2)>>2]=k;k=e<<2;h=c[b+276>>2]|0;c[f+(k<<2)>>2]=c[b+272>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+284>>2]|0;c[f+(k<<2)>>2]=c[b+280>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+292>>2]|0;c[f+(k<<2)>>2]=c[b+288>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+300>>2]|0;c[f+(k<<2)>>2]=c[b+296>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+308>>2]|0;c[f+(k<<2)>>2]=c[b+304>>2];c[f+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+316>>2]|0;c[f+(k<<2)>>2]=c[b+312>>2];c[f+((k|1)<<2)>>2]=h;k=c[b+324>>2]|0;c[g>>2]=c[b+320>>2];c[g+4>>2]=k;k=c[b+332>>2]|0;c[g+(j<<2)>>2]=c[b+328>>2];c[g+((j|1)<<2)>>2]=k;k=e<<2;h=c[b+340>>2]|0;c[g+(k<<2)>>2]=c[b+336>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+348>>2]|0;c[g+(k<<2)>>2]=c[b+344>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+356>>2]|0;c[g+(k<<2)>>2]=c[b+352>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+364>>2]|0;c[g+(k<<2)>>2]=c[b+360>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;h=c[b+372>>2]|0;c[g+(k<<2)>>2]=c[b+368>>2];c[g+((k|1)<<2)>>2]=h;k=k+j|0;j=c[b+380>>2]|0;c[g+(k<<2)>>2]=c[b+376>>2];c[g+((k|1)<<2)>>2]=j;i=l;return}function tc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;y=i;r=c[b+4>>2]|0;s=Z(c[b+8>>2]|0,r)|0;w=(e>>>0)%(r>>>0)|0;x=c[b>>2]|0;u=e-w|0;b=(u<<8)+(w<<4)|0;v=s<<8;w=w<<3;p=r<<4;o=r<<2&1073741820;l=o<<1;m=l+o|0;n=0;do{k=c[3344+(n<<2)>>2]|0;j=c[3408+(n<<2)>>2]|0;e=(j<<4)+k|0;h=f+e|0;j=b+k+(Z(j,p)|0)|0;k=x+j|0;q=c[g+(n<<6)>>2]|0;if((q|0)==16777215){j=c[f+(e+16)>>2]|0;c[k>>2]=c[h>>2];c[k+(o<<2)>>2]=j;j=c[f+(e+48)>>2]|0;c[k+(l<<2)>>2]=c[f+(e+32)>>2];c[k+(m<<2)>>2]=j}else{A=d[f+(e+1)>>0]|0;z=c[g+(n<<6)+4>>2]|0;a[k>>0]=a[3472+(q+512+(d[h>>0]|0))>>0]|0;q=d[f+(e+2)>>0]|0;t=c[g+(n<<6)+8>>2]|0;a[x+(j+1)>>0]=a[3472+((A|512)+z)>>0]|0;k=d[f+(e+3)>>0]|0;h=c[g+(n<<6)+12>>2]|0;a[x+(j+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(j+3)>>0]=a[3472+(h+512+k)>>0]|0;k=j+p|0;h=d[f+(e+17)>>0]|0;j=c[g+(n<<6)+20>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+16>>2]|0)+512+(d[f+(e+16)>>0]|0))>>0]|0;q=d[f+(e+18)>>0]|0;t=c[g+(n<<6)+24>>2]|0;a[x+(k+1)>>0]=a[3472+((h|512)+j)>>0]|0;j=d[f+(e+19)>>0]|0;h=c[g+(n<<6)+28>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(h+512+j)>>0]|0;k=k+p|0;j=d[f+(e+33)>>0]|0;h=c[g+(n<<6)+36>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+32>>2]|0)+512+(d[f+(e+32)>>0]|0))>>0]|0;q=d[f+(e+34)>>0]|0;t=c[g+(n<<6)+40>>2]|0;a[x+(k+1)>>0]=a[3472+((j|512)+h)>>0]|0;h=d[f+(e+35)>>0]|0;j=c[g+(n<<6)+44>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(j+512+h)>>0]|0;k=k+p|0;h=d[f+(e+49)>>0]|0;j=c[g+(n<<6)+52>>2]|0;a[x+k>>0]=a[3472+((c[g+(n<<6)+48>>2]|0)+512+(d[f+(e+48)>>0]|0))>>0]|0;q=d[f+(e+50)>>0]|0;t=c[g+(n<<6)+56>>2]|0;a[x+(k+1)>>0]=a[3472+((h|512)+j)>>0]|0;j=d[f+(e+51)>>0]|0;h=c[g+(n<<6)+60>>2]|0;a[x+(k+2)>>0]=a[3472+(t+512+q)>>0]|0;a[x+(k+3)>>0]=a[3472+(h+512+j)>>0]|0}n=n+1|0}while((n|0)!=16);t=s<<6;s=r<<3&2147483640;r=f+256|0;f=f+320|0;l=w+v+(u<<6)|0;p=s>>>2;j=s>>>1;k=j+p|0;o=16;do{q=o&3;h=c[3344+(q<<2)>>2]|0;q=c[3408+(q<<2)>>2]|0;e=o>>>0>19;m=e?f:r;n=(q<<3)+h|0;b=m+n|0;q=l+(e?t:0)+h+(Z(q,s)|0)|0;h=x+q|0;e=c[g+(o<<6)>>2]|0;if((e|0)==16777215){z=c[m+(n+8)>>2]|0;c[h>>2]=c[b>>2];c[h+(p<<2)>>2]=z;z=c[m+(n+24)>>2]|0;c[h+(j<<2)>>2]=c[m+(n+16)>>2];c[h+(k<<2)>>2]=z}else{v=d[m+(n+1)>>0]|0;z=c[g+(o<<6)+4>>2]|0;a[h>>0]=a[3472+(e+512+(d[b>>0]|0))>>0]|0;w=d[m+(n+2)>>0]|0;u=c[g+(o<<6)+8>>2]|0;a[x+(q+1)>>0]=a[3472+((v|512)+z)>>0]|0;z=d[m+(n+3)>>0]|0;v=c[g+(o<<6)+12>>2]|0;a[x+(q+2)>>0]=a[3472+(u+512+w)>>0]|0;a[x+(q+3)>>0]=a[3472+(v+512+z)>>0]|0;z=q+s|0;v=d[m+(n+9)>>0]|0;w=c[g+(o<<6)+20>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+16>>2]|0)+512+(d[m+(n+8)>>0]|0))>>0]|0;u=d[m+(n+10)>>0]|0;q=c[g+(o<<6)+24>>2]|0;a[x+(z+1)>>0]=a[3472+((v|512)+w)>>0]|0;w=d[m+(n+11)>>0]|0;v=c[g+(o<<6)+28>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(v+512+w)>>0]|0;z=z+s|0;w=d[m+(n+17)>>0]|0;v=c[g+(o<<6)+36>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+32>>2]|0)+512+(d[m+(n+16)>>0]|0))>>0]|0;u=d[m+(n+18)>>0]|0;q=c[g+(o<<6)+40>>2]|0;a[x+(z+1)>>0]=a[3472+((w|512)+v)>>0]|0;v=d[m+(n+19)>>0]|0;w=c[g+(o<<6)+44>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(w+512+v)>>0]|0;z=z+s|0;v=d[m+(n+25)>>0]|0;w=c[g+(o<<6)+52>>2]|0;a[x+z>>0]=a[3472+((c[g+(o<<6)+48>>2]|0)+512+(d[m+(n+24)>>0]|0))>>0]|0;u=d[m+(n+26)>>0]|0;q=c[g+(o<<6)+56>>2]|0;a[x+(z+1)>>0]=a[3472+((v|512)+w)>>0]|0;w=d[m+(n+27)>>0]|0;v=c[g+(o<<6)+60>>2]|0;a[x+(z+2)>>0]=a[3472+(q+512+u)>>0]|0;a[x+(z+3)>>0]=a[3472+(v+512+w)>>0]|0}o=o+1|0}while((o|0)!=24);i=y;return}function uc(e,f){e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0;bb=i;i=i+176|0;ia=bb+40|0;La=bb;ea=c[e+4>>2]|0;ka=e+8|0;Wa=c[ka>>2]|0;g=Z(Wa,ea)|0;if(!Wa){i=bb;return}Za=ia+24|0;_a=ia+16|0;$a=ia+8|0;la=ia+100|0;ma=ia+68|0;na=ia+36|0;oa=ia+4|0;Ma=ia+120|0;Na=ia+112|0;Pa=ia+104|0;Qa=ia+96|0;Ra=ia+88|0;Sa=ia+80|0;Ta=ia+72|0;Ua=ia+64|0;Va=ia+56|0;Wa=ia+48|0;Xa=ia+40|0;Ya=ia+32|0;pa=ia+124|0;qa=ia+116|0;ra=ia+108|0;sa=ia+92|0;ta=ia+84|0;ua=ia+76|0;va=ia+60|0;wa=ia+52|0;xa=ia+44|0;ya=ia+28|0;za=ia+20|0;Aa=ia+12|0;ha=La+28|0;ja=La+32|0;Ka=La+24|0;Da=ea<<4;Ja=0-Da|0;Ca=Ja<<1;Ha=Z(ea,-48)|0;Ia=ea<<5;Ea=Ja<<2;Ga=ea*48|0;Ba=ea<<6;ga=La+24|0;fa=La+12|0;Fa=g<<8;ba=g<<6;ca=ea<<3;W=Da|4;Y=La+16|0;$=La+20|0;da=La+12|0;X=La+4|0;_=La+8|0;U=0;aa=0;V=f;while(1){f=c[V+8>>2]|0;do if((f|0)!=1){T=V+200|0;n=c[T>>2]|0;do if(!n)g=1;else{if((f|0)==2?(c[V+4>>2]|0)!=(c[n+4>>2]|0):0){g=1;break}g=5}while(0);S=V+204|0;l=c[S>>2]|0;do if(l){if((f|0)==2?(c[V+4>>2]|0)!=(c[l+4>>2]|0):0)break;g=g|2}while(0);R=(g&2|0)==0;do if(R){c[Za>>2]=0;c[_a>>2]=0;c[$a>>2]=0;c[ia>>2]=0;m=0}else{if((c[V>>2]|0)>>>0<=5?(c[l>>2]|0)>>>0<=5:0){if((b[V+28>>1]|0)==0?(b[l+48>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[l+124>>2]|0)?(B=(b[V+132>>1]|0)-(b[l+172>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){h=(b[V+134>>1]|0)-(b[l+174>>1]|0)|0;h=(((h|0)>-1?h:0-h|0)|0)>3&1}else h=1;else h=2;c[ia>>2]=h;if((b[V+30>>1]|0)==0?(b[l+50>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[l+124>>2]|0)?(B=(b[V+136>>1]|0)-(b[l+176>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){j=(b[V+138>>1]|0)-(b[l+178>>1]|0)|0;j=(((j|0)>-1?j:0-j|0)|0)>3&1}else j=1;else j=2;c[$a>>2]=j;if((b[V+36>>1]|0)==0?(b[l+56>>1]|0)==0:0)if((c[V+120>>2]|0)==(c[l+128>>2]|0)?(B=(b[V+148>>1]|0)-(b[l+188>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){k=(b[V+150>>1]|0)-(b[l+190>>1]|0)|0;k=(((k|0)>-1?k:0-k|0)|0)>3&1}else k=1;else k=2;c[_a>>2]=k;if((b[V+38>>1]|0)==0?(b[l+58>>1]|0)==0:0)if((c[V+120>>2]|0)==(c[l+128>>2]|0)?(B=(b[V+152>>1]|0)-(b[l+192>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){f=(b[V+154>>1]|0)-(b[l+194>>1]|0)|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=1;else f=2;c[Za>>2]=f;m=(j|h|k|f|0)!=0&1;break}c[Za>>2]=4;c[_a>>2]=4;c[$a>>2]=4;c[ia>>2]=4;m=1}while(0);Q=(g&4|0)==0;do if(Q){c[la>>2]=0;c[ma>>2]=0;c[na>>2]=0;c[oa>>2]=0;k=c[V>>2]|0}else{k=c[V>>2]|0;if(k>>>0<=5?(c[n>>2]|0)>>>0<=5:0){if((b[V+28>>1]|0)==0?(b[n+38>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[n+120>>2]|0)?(B=(b[V+132>>1]|0)-(b[n+152>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){j=(b[V+134>>1]|0)-(b[n+154>>1]|0)|0;j=(((j|0)>-1?j:0-j|0)|0)>3&1}else j=1;else j=2;c[oa>>2]=j;if((b[V+32>>1]|0)==0?(b[n+42>>1]|0)==0:0)if((c[V+116>>2]|0)==(c[n+120>>2]|0)?(B=(b[V+140>>1]|0)-(b[n+160>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){h=(b[V+142>>1]|0)-(b[n+162>>1]|0)|0;h=(((h|0)>-1?h:0-h|0)|0)>3&1}else h=1;else h=2;c[na>>2]=h;if((b[V+44>>1]|0)==0?(b[n+54>>1]|0)==0:0)if((c[V+124>>2]|0)==(c[n+128>>2]|0)?(B=(b[V+164>>1]|0)-(b[n+184>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){f=(b[V+166>>1]|0)-(b[n+186>>1]|0)|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=1;else f=2;c[ma>>2]=f;if((b[V+48>>1]|0)==0?(b[n+58>>1]|0)==0:0)if((c[V+124>>2]|0)==(c[n+128>>2]|0)?(B=(b[V+172>>1]|0)-(b[n+192>>1]|0)|0,(((B|0)>-1?B:0-B|0)|0)<=3):0){l=(b[V+174>>1]|0)-(b[n+194>>1]|0)|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=1;else l=2;c[la>>2]=l;if(m)break;m=(h|j|f|l|0)!=0&1;break}c[la>>2]=4;c[ma>>2]=4;c[na>>2]=4;c[oa>>2]=4;m=1}while(0);if(k>>>0<=5){do if((db(k)|0)!=1){f=c[V>>2]|0;if((f|0)==2){w=V+28|0;x=b[V+32>>1]|0;if(!(x<<16>>16))f=(b[w>>1]|0)!=0?2:0;else f=2;c[Ya>>2]=f;q=b[V+34>>1]|0;A=q<<16>>16==0;if(A)f=(b[V+30>>1]|0)!=0?2:0;else f=2;c[Xa>>2]=f;g=b[V+40>>1]|0;z=g<<16>>16==0;if(z)l=(b[V+36>>1]|0)!=0?2:0;else l=2;c[Wa>>2]=l;v=b[V+42>>1]|0;y=v<<16>>16==0;if(y)l=(b[V+38>>1]|0)!=0?2:0;else l=2;c[Va>>2]=l;h=b[V+48>>1]|0;if(!(h<<16>>16))l=(b[V+44>>1]|0)!=0?2:0;else l=2;c[Qa>>2]=l;k=b[V+50>>1]|0;B=k<<16>>16==0;if(B)l=(b[V+46>>1]|0)!=0?2:0;else l=2;c[Pa>>2]=l;p=b[V+56>>1]|0;f=p<<16>>16==0;if(f)n=(b[V+52>>1]|0)!=0?2:0;else n=2;c[Na>>2]=n;j=(b[V+58>>1]|0)==0;if(j)n=(b[V+54>>1]|0)!=0?2:0;else n=2;c[Ma>>2]=n;r=b[V+44>>1]|0;o=b[V+166>>1]|0;n=b[V+142>>1]|0;do if(!((r|x)<<16>>16)){u=(b[V+164>>1]|0)-(b[V+140>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){n=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){n=1;break}n=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else n=2;while(0);c[Ua>>2]=n;s=b[V+46>>1]|0;o=b[V+170>>1]|0;n=b[V+146>>1]|0;do if(!((s|q)<<16>>16)){u=(b[V+168>>1]|0)-(b[V+144>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[Ta>>2]=o;t=b[V+52>>1]|0;o=b[V+182>>1]|0;n=b[V+158>>1]|0;do if(!((t|g)<<16>>16)){u=(b[V+180>>1]|0)-(b[V+156>>1]|0)|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}u=o-n|0;if((((u|0)>-1?u:0-u|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Sa>>2]=o;u=b[V+54>>1]|0;o=b[V+186>>1]|0;n=b[V+162>>1]|0;do if(!((u|v)<<16>>16)){v=(b[V+184>>1]|0)-(b[V+160>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){o=1;break}v=o-n|0;if((((v|0)>-1?v:0-v|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Ra>>2]=o;l=b[V+30>>1]|0;if(!(l<<16>>16))o=(b[w>>1]|0)!=0?2:0;else o=2;c[Aa>>2]=o;n=b[V+36>>1]|0;if(!(n<<16>>16))o=l<<16>>16!=0?2:0;else o=2;c[za>>2]=o;if(!(b[V+38>>1]|0))o=n<<16>>16!=0?2:0;else o=2;c[ya>>2]=o;if(A)n=x<<16>>16!=0?2:0;else n=2;c[xa>>2]=n;if(z)l=q<<16>>16!=0?2:0;else l=2;c[wa>>2]=l;if(y)l=g<<16>>16!=0?2:0;else l=2;c[va>>2]=l;if(!(s<<16>>16))l=r<<16>>16!=0?2:0;else l=2;c[ua>>2]=l;if(!(t<<16>>16))l=s<<16>>16!=0?2:0;else l=2;c[ta>>2]=l;if(!(u<<16>>16))l=t<<16>>16!=0?2:0;else l=2;c[sa>>2]=l;if(B)h=h<<16>>16!=0?2:0;else h=2;c[ra>>2]=h;if(f)f=k<<16>>16!=0?2:0;else f=2;c[qa>>2]=f;if(j)f=p<<16>>16!=0?2:0;else f=2;c[pa>>2]=f;break}else if((f|0)==3){j=V+28|0;v=b[V+32>>1]|0;if(!(v<<16>>16))f=(b[j>>1]|0)!=0?2:0;else f=2;c[Ya>>2]=f;B=b[V+34>>1]|0;p=B<<16>>16==0;if(p)h=(b[V+30>>1]|0)!=0?2:0;else h=2;c[Xa>>2]=h;z=b[V+40>>1]|0;if(!(z<<16>>16))k=(b[V+36>>1]|0)!=0?2:0;else k=2;c[Wa>>2]=k;o=b[V+42>>1]|0;h=o<<16>>16==0;if(h)l=(b[V+38>>1]|0)!=0?2:0;else l=2;c[Va>>2]=l;f=b[V+44>>1]|0;if(!(f<<16>>16))l=v<<16>>16!=0?2:0;else l=2;c[Ua>>2]=l;A=b[V+46>>1]|0;g=A<<16>>16==0;if(g)l=B<<16>>16!=0?2:0;else l=2;c[Ta>>2]=l;y=b[V+52>>1]|0;if(!(y<<16>>16))l=z<<16>>16!=0?2:0;else l=2;c[Sa>>2]=l;k=b[V+54>>1]|0;q=k<<16>>16==0;if(q)l=o<<16>>16!=0?2:0;else l=2;c[Ra>>2]=l;r=b[V+48>>1]|0;if(!(r<<16>>16))n=f<<16>>16!=0?2:0;else n=2;c[Qa>>2]=n;x=b[V+50>>1]|0;s=x<<16>>16==0;if(s)n=A<<16>>16!=0?2:0;else n=2;c[Pa>>2]=n;w=b[V+56>>1]|0;if(!(w<<16>>16))o=y<<16>>16!=0?2:0;else o=2;c[Na>>2]=o;u=(b[V+58>>1]|0)==0;if(u)o=k<<16>>16!=0?2:0;else o=2;c[Ma>>2]=o;t=b[V+30>>1]|0;if(!(t<<16>>16))o=(b[j>>1]|0)!=0?2:0;else o=2;c[Aa>>2]=o;if(!(b[V+38>>1]|0))o=(b[V+36>>1]|0)!=0?2:0;else o=2;c[ya>>2]=o;if(p)n=v<<16>>16!=0?2:0;else n=2;c[xa>>2]=n;if(h)n=z<<16>>16!=0?2:0;else n=2;c[va>>2]=n;if(g)l=f<<16>>16!=0?2:0;else l=2;c[ua>>2]=l;if(q)l=y<<16>>16!=0?2:0;else l=2;c[sa>>2]=l;if(s)l=r<<16>>16!=0?2:0;else l=2;c[ra>>2]=l;if(u)l=w<<16>>16!=0?2:0;else l=2;c[pa>>2]=l;l=b[V+150>>1]|0;k=b[V+138>>1]|0;do if(!((b[V+36>>1]|t)<<16>>16)){v=(b[V+148>>1]|0)-(b[V+136>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){l=1;break}v=l-k|0;if((((v|0)>-1?v:0-v|0)|0)>3){l=1;break}l=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else l=2;while(0);c[za>>2]=l;l=b[V+158>>1]|0;k=b[V+146>>1]|0;do if(!((z|B)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+144>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}B=l-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}k=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else k=2;while(0);c[wa>>2]=k;l=b[V+182>>1]|0;k=b[V+170>>1]|0;do if(!((y|A)<<16>>16)){B=(b[V+180>>1]|0)-(b[V+168>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}B=l-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else f=2;while(0);c[ta>>2]=f;f=b[V+190>>1]|0;g=b[V+178>>1]|0;do if(!((w|x)<<16>>16)){B=(b[V+188>>1]|0)-(b[V+176>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}B=f-g|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else f=2;while(0);c[qa>>2]=f;break}else{K=b[V+32>>1]|0;z=b[V+28>>1]|0;P=b[V+142>>1]|0;q=b[V+134>>1]|0;if(!((z|K)<<16>>16)){B=(b[V+140>>1]|0)-(b[V+132>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)k=1;else{k=P-q|0;k=(((k|0)>-1?k:0-k|0)|0)>3&1}}else k=2;c[Ya>>2]=k;L=b[V+34>>1]|0;y=b[V+30>>1]|0;O=b[V+146>>1]|0;r=b[V+138>>1]|0;if(!((y|L)<<16>>16)){B=(b[V+144>>1]|0)-(b[V+136>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)l=1;else{l=O-r|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}}else l=2;c[Xa>>2]=l;M=b[V+40>>1]|0;x=b[V+36>>1]|0;N=b[V+158>>1]|0;s=b[V+150>>1]|0;if(!((x|M)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+148>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3)n=1;else{n=N-s|0;n=(((n|0)>-1?n:0-n|0)|0)>3&1}}else n=2;c[Wa>>2]=n;n=b[V+42>>1]|0;B=b[V+38>>1]|0;J=b[V+162>>1]|0;A=b[V+154>>1]|0;if(!((B|n)<<16>>16)){w=(b[V+160>>1]|0)-(b[V+152>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3)o=1;else{o=J-A|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}}else o=2;c[Va>>2]=o;D=b[V+44>>1]|0;I=b[V+166>>1]|0;do if(!((D|K)<<16>>16)){w=(b[V+164>>1]|0)-(b[V+140>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3)o=1;else{w=I-P|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}}else o=2;while(0);c[Ua>>2]=o;E=b[V+46>>1]|0;H=b[V+170>>1]|0;do if(!((E|L)<<16>>16)){w=(b[V+168>>1]|0)-(b[V+144>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}w=H-O|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+124>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[Ta>>2]=o;F=b[V+52>>1]|0;G=b[V+182>>1]|0;do if(!((F|M)<<16>>16)){w=(b[V+180>>1]|0)-(b[V+156>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}w=G-N|0;if((((w|0)>-1?w:0-w|0)|0)>3){o=1;break}o=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else o=2;while(0);c[Sa>>2]=o;g=b[V+54>>1]|0;l=b[V+186>>1]|0;do if(!((g|n)<<16>>16)){w=(b[V+184>>1]|0)-(b[V+160>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}w=l-J|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=(c[V+128>>2]|0)!=(c[V+120>>2]|0)&1}else u=2;while(0);c[Ra>>2]=u;f=b[V+48>>1]|0;C=b[V+174>>1]|0;do if(!((f|D)<<16>>16)){w=(b[V+172>>1]|0)-(b[V+164>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=C-I|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Qa>>2]=u;h=b[V+50>>1]|0;k=b[V+178>>1]|0;do if(!((h|E)<<16>>16)){w=(b[V+176>>1]|0)-(b[V+168>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=k-H|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Pa>>2]=u;j=b[V+56>>1]|0;p=b[V+190>>1]|0;do if(!((j|F)<<16>>16)){w=(b[V+188>>1]|0)-(b[V+180>>1]|0)|0;if((((w|0)>-1?w:0-w|0)|0)>3){u=1;break}u=p-G|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Na>>2]=u;w=b[V+58>>1]|0;t=b[V+194>>1]|0;do if(!((w|g)<<16>>16)){v=(b[V+192>>1]|0)-(b[V+184>>1]|0)|0;if((((v|0)>-1?v:0-v|0)|0)>3){v=1;break}v=t-l|0;v=(((v|0)>-1?v:0-v|0)|0)>3&1}else v=2;while(0);c[Ma>>2]=v;do if(!((y|z)<<16>>16)){z=(b[V+136>>1]|0)-(b[V+132>>1]|0)|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}u=r-q|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[Aa>>2]=u;do if(!((x|y)<<16>>16)){z=(b[V+148>>1]|0)-(b[V+136>>1]|0)|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}z=s-r|0;if((((z|0)>-1?z:0-z|0)|0)>3){u=1;break}u=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else u=2;while(0);c[za>>2]=u;do if(!((B|x)<<16>>16)){B=(b[V+152>>1]|0)-(b[V+148>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){u=1;break}u=A-s|0;u=(((u|0)>-1?u:0-u|0)|0)>3&1}else u=2;while(0);c[ya>>2]=u;do if(!((L|K)<<16>>16)){B=(b[V+144>>1]|0)-(b[V+140>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=O-P|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}else o=2;while(0);c[xa>>2]=o;do if(!((M|L)<<16>>16)){B=(b[V+156>>1]|0)-(b[V+144>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}B=N-O|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=(c[V+120>>2]|0)!=(c[V+116>>2]|0)&1}else o=2;while(0);c[wa>>2]=o;do if(!((n|M)<<16>>16)){B=(b[V+160>>1]|0)-(b[V+156>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){o=1;break}o=J-N|0;o=(((o|0)>-1?o:0-o|0)|0)>3&1}else o=2;while(0);c[va>>2]=o;do if(!((E|D)<<16>>16)){B=(b[V+168>>1]|0)-(b[V+164>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}n=H-I|0;n=(((n|0)>-1?n:0-n|0)|0)>3&1}else n=2;while(0);c[ua>>2]=n;do if(!((F|E)<<16>>16)){B=(b[V+180>>1]|0)-(b[V+168>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}B=G-H|0;if((((B|0)>-1?B:0-B|0)|0)>3){n=1;break}n=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else n=2;while(0);c[ta>>2]=n;do if(!((g|F)<<16>>16)){B=(b[V+184>>1]|0)-(b[V+180>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){l=1;break}l=l-G|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=2;while(0);c[sa>>2]=l;do if(!((h|f)<<16>>16)){B=(b[V+176>>1]|0)-(b[V+172>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){l=1;break}l=k-C|0;l=(((l|0)>-1?l:0-l|0)|0)>3&1}else l=2;while(0);c[ra>>2]=l;do if(!((j|h)<<16>>16)){B=(b[V+188>>1]|0)-(b[V+176>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}B=p-k|0;if((((B|0)>-1?B:0-B|0)|0)>3){k=1;break}k=(c[V+128>>2]|0)!=(c[V+124>>2]|0)&1}else k=2;while(0);c[qa>>2]=k;do if(!((w|j)<<16>>16)){B=(b[V+192>>1]|0)-(b[V+188>>1]|0)|0;if((((B|0)>-1?B:0-B|0)|0)>3){f=1;break}f=t-p|0;f=(((f|0)>-1?f:0-f|0)|0)>3&1}else f=2;while(0);c[pa>>2]=f;break}}else vc(V,ia);while(0);if(!(m|c[Ya>>2]|c[Xa>>2]|c[Wa>>2]|c[Va>>2]|c[Ua>>2]|c[Ta>>2]|c[Sa>>2]|c[Ra>>2]|c[Qa>>2]|c[Pa>>2]|c[Na>>2]|c[Ma>>2]|c[Aa>>2]|c[za>>2]|c[ya>>2]|c[xa>>2]|c[wa>>2]|c[va>>2]|c[ua>>2]|c[ta>>2]|c[sa>>2]|c[ra>>2]|c[qa>>2]|c[pa>>2]))break}else{c[Ma>>2]=3;c[Na>>2]=3;c[Pa>>2]=3;c[Qa>>2]=3;c[Ra>>2]=3;c[Sa>>2]=3;c[Ta>>2]=3;c[Ua>>2]=3;c[Va>>2]=3;c[Wa>>2]=3;c[Xa>>2]=3;c[Ya>>2]=3;c[pa>>2]=3;c[qa>>2]=3;c[ra>>2]=3;c[sa>>2]=3;c[ta>>2]=3;c[ua>>2]=3;c[va>>2]=3;c[wa>>2]=3;c[xa>>2]=3;c[ya>>2]=3;c[za>>2]=3;c[Aa>>2]=3}J=V+20|0;g=c[J>>2]|0;L=V+12|0;k=Oa(0,51,(c[L>>2]|0)+g|0)|0;K=V+16|0;h=Oa(0,51,(c[K>>2]|0)+g|0)|0;j=d[6864+k>>0]|0;c[ha>>2]=j;h=d[6920+h>>0]|0;c[ja>>2]=h;k=6976+(k*3|0)|0;c[Ka>>2]=k;do if(!R){l=c[(c[S>>2]|0)+20>>2]|0;if((l|0)==(g|0)){c[X>>2]=j;c[_>>2]=h;c[La>>2]=k;break}else{A=(g+1+l|0)>>>1;B=Oa(0,51,(c[L>>2]|0)+A|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[X>>2]=d[6864+B>>0];c[_>>2]=d[6920+A>>0];c[La>>2]=6976+(B*3|0);break}}while(0);do if(!Q){f=c[(c[T>>2]|0)+20>>2]|0;if((f|0)==(g|0)){c[Y>>2]=c[ha>>2];c[$>>2]=c[ja>>2];c[da>>2]=c[Ka>>2];break}else{A=(g+1+f|0)>>>1;B=Oa(0,51,(c[L>>2]|0)+A|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[Y>>2]=d[6864+B>>0];c[$>>2]=d[6920+A>>0];c[da>>2]=6976+(B*3|0);break}}while(0);M=Z(aa,ea)|0;P=3;o=0;O=(c[e>>2]|0)+((M<<8)+(U<<4))|0;N=ia;while(1){l=c[N+4>>2]|0;if(l)wc(O,l,fa,Da);l=c[N+12>>2]|0;if(l)wc(O+4|0,l,ga,Da);k=N+16|0;m=c[N+20>>2]|0;if(m)wc(O+8|0,m,ga,Da);j=N+24|0;m=c[N+28>>2]|0;if(m)wc(O+12|0,m,ga,Da);n=c[N>>2]|0;l=N+8|0;m=c[l>>2]|0;a:do if(((n|0)==(m|0)?(n|0)==(c[k>>2]|0):0)?(n|0)==(c[j>>2]|0):0){if(!n)break;y=c[La+(o*12|0)+4>>2]|0;x=c[La+(o*12|0)+8>>2]|0;if(n>>>0<4){t=d[(c[La+(o*12|0)>>2]|0)+(n+-1)>>0]|0;k=0-t|0;j=t+1|0;f=O;h=16;while(1){o=f+Ca|0;s=d[o>>0]|0;u=f+Ja|0;r=d[u>>0]|0;q=d[f>>0]|0;m=f+Da|0;g=d[m>>0]|0;B=r-q|0;do if(((B|0)>-1?B:0-B|0)>>>0>>0){B=s-r|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=g-q|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;n=d[f+Ha>>0]|0;B=n-r|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[o>>0]=(Oa(k,t,((r+1+q|0)>>>1)-(s<<1)+n>>1)|0)+s;o=j}else o=t;n=d[f+Ia>>0]|0;B=n-q|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[m>>0]=(Oa(k,t,((r+1+q|0)>>>1)-(g<<1)+n>>1)|0)+g;o=o+1|0}A=Oa(0-o|0,o,s+4-g+(q-r<<2)>>3)|0;B=a[3472+((q|512)-A)>>0]|0;a[u>>0]=a[3472+(A+(r|512))>>0]|0;a[f>>0]=B}while(0);h=h+-1|0;if(!h)break a;else f=f+1|0}}n=(y>>>2)+2|0;t=O;u=16;while(1){m=t+Ca|0;f=d[m>>0]|0;l=t+Ja|0;g=d[l>>0]|0;p=d[t>>0]|0;k=t+Da|0;q=d[k>>0]|0;o=g-p|0;o=(o|0)>-1?o:0-o|0;b:do if(o>>>0>>0){B=f-g|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=q-p|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;j=t+Ha|0;r=d[j>>0]|0;h=t+Ia|0;s=d[h>>0]|0;do if(o>>>0>>0){B=r-g|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){B=g+f+p|0;a[l>>0]=(q+4+(B<<1)+r|0)>>>3;a[m>>0]=(B+2+r|0)>>>2;a[j>>0]=(B+4+(r*3|0)+(d[t+Ea>>0]<<1)|0)>>>3}else a[l>>0]=(g+2+(f<<1)+q|0)>>>2;B=s-p|0;if(((B|0)>-1?B:0-B|0)>>>0>=x>>>0)break;B=p+g+q|0;a[t>>0]=(f+4+(B<<1)+s|0)>>>3;a[k>>0]=(B+2+s|0)>>>2;a[h>>0]=(B+4+(s*3|0)+(d[t+Ga>>0]<<1)|0)>>>3;break b}else a[l>>0]=(g+2+(f<<1)+q|0)>>>2;while(0);a[t>>0]=(f+2+p+(q<<1)|0)>>>2}while(0);u=u+-1|0;if(!u)break;else t=t+1|0}}else ab=311;while(0);do if((ab|0)==311){ab=0;if(n){xc(O,n,La+(o*12|0)|0,Da);m=c[l>>2]|0}if(m)xc(O+4|0,m,La+(o*12|0)|0,Da);m=c[k>>2]|0;if(m)xc(O+8|0,m,La+(o*12|0)|0,Da);l=c[j>>2]|0;if(!l)break;xc(O+12|0,l,La+(o*12|0)|0,Da)}while(0);if(!P)break;else{P=P+-1|0;o=2;O=O+Ba|0;N=N+32|0}}h=c[V+24>>2]|0;g=c[192+((Oa(0,51,(c[J>>2]|0)+h|0)|0)<<2)>>2]|0;m=Oa(0,51,(c[L>>2]|0)+g|0)|0;j=Oa(0,51,(c[K>>2]|0)+g|0)|0;k=d[6864+m>>0]|0;c[ha>>2]=k;j=d[6920+j>>0]|0;c[ja>>2]=j;m=6976+(m*3|0)|0;c[Ka>>2]=m;do if(!R){l=c[(c[S>>2]|0)+20>>2]|0;if((l|0)==(c[J>>2]|0)){c[X>>2]=k;c[_>>2]=j;c[La>>2]=m;break}else{A=(g+1+(c[192+((Oa(0,51,l+h|0)|0)<<2)>>2]|0)|0)>>>1;B=Oa(0,51,A+(c[L>>2]|0)|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[X>>2]=d[6864+B>>0];c[_>>2]=d[6920+A>>0];c[La>>2]=6976+(B*3|0);break}}while(0);do if(!Q){f=c[(c[T>>2]|0)+20>>2]|0;if((f|0)==(c[J>>2]|0)){c[Y>>2]=c[ha>>2];c[$>>2]=c[ja>>2];c[da>>2]=c[Ka>>2];break}else{A=(g+1+(c[192+((Oa(0,51,f+h|0)|0)<<2)>>2]|0)|0)>>>1;B=Oa(0,51,A+(c[L>>2]|0)|0)|0;A=Oa(0,51,(c[K>>2]|0)+A|0)|0;c[Y>>2]=d[6864+B>>0];c[$>>2]=d[6920+A>>0];c[da>>2]=6976+(B*3|0);break}}while(0);j=c[e>>2]|0;l=(U<<3)+Fa+(M<<6)|0;n=j+l|0;l=j+(l+ba)|0;j=0;h=ia;o=0;while(1){g=h+4|0;f=c[g>>2]|0;if(f){yc(n,f,fa,ca);yc(l,c[g>>2]|0,fa,ca)}g=h+36|0;f=c[g>>2]|0;if(f){yc(n+Da|0,f,fa,ca);yc(l+Da|0,c[g>>2]|0,fa,ca)}m=h+16|0;g=h+20|0;f=c[g>>2]|0;if(f){yc(n+4|0,f,ga,ca);yc(l+4|0,c[g>>2]|0,ga,ca)}g=h+52|0;f=c[g>>2]|0;if(f){yc(n+W|0,f,ga,ca);yc(l+W|0,c[g>>2]|0,ga,ca)}g=c[h>>2]|0;k=h+8|0;f=c[k>>2]|0;do if((g|0)==(f|0)){if((g|0)!=(c[m>>2]|0)){ab=342;break}if((g|0)!=(c[h+24>>2]|0)){ab=342;break}if(!g)break;B=La+(j*12|0)|0;zc(n,g,B,ca);zc(l,c[h>>2]|0,B,ca)}else ab=342;while(0);do if((ab|0)==342){ab=0;if(g){f=La+(j*12|0)|0;Ac(n,g,f,ca);Ac(l,c[h>>2]|0,f,ca);f=c[k>>2]|0}if(f){B=La+(j*12|0)|0;Ac(n+2|0,f,B,ca);Ac(l+2|0,c[k>>2]|0,B,ca)}f=c[m>>2]|0;if(f){B=La+(j*12|0)|0;Ac(n+4|0,f,B,ca);Ac(l+4|0,c[m>>2]|0,B,ca)}g=h+24|0;f=c[g>>2]|0;if(!f)break;B=La+(j*12|0)|0;Ac(n+6|0,f,B,ca);Ac(l+6|0,c[g>>2]|0,B,ca)}while(0);o=o+1|0;if((o|0)==2)break;else{n=n+Ia|0;l=l+Ia|0;j=2;h=h+64|0}}}while(0);f=U+1|0;g=(f|0)==(ea|0);aa=(g&1)+aa|0;if(aa>>>0>=(c[ka>>2]|0)>>>0)break;else{U=g?0:f;V=V+216|0}}i=bb;return}function vc(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;B=i;l=a+28|0;y=b[a+32>>1]|0;if(!(y<<16>>16))e=(b[l>>1]|0)!=0?2:0;else e=2;c[d+32>>2]=e;z=b[a+34>>1]|0;x=z<<16>>16==0;if(x)e=(b[a+30>>1]|0)!=0?2:0;else e=2;c[d+40>>2]=e;A=b[a+40>>1]|0;v=A<<16>>16==0;if(v)e=(b[a+36>>1]|0)!=0?2:0;else e=2;c[d+48>>2]=e;f=b[a+42>>1]|0;w=f<<16>>16==0;if(w)e=(b[a+38>>1]|0)!=0?2:0;else e=2;c[d+56>>2]=e;s=b[a+44>>1]|0;if(!(s<<16>>16))e=y<<16>>16!=0?2:0;else e=2;c[d+64>>2]=e;t=b[a+46>>1]|0;p=t<<16>>16==0;if(p)e=z<<16>>16!=0?2:0;else e=2;c[d+72>>2]=e;u=b[a+52>>1]|0;q=u<<16>>16==0;if(q)e=A<<16>>16!=0?2:0;else e=2;c[d+80>>2]=e;g=b[a+54>>1]|0;r=g<<16>>16==0;if(r)e=f<<16>>16!=0?2:0;else e=2;c[d+88>>2]=e;m=b[a+48>>1]|0;if(!(m<<16>>16))e=s<<16>>16!=0?2:0;else e=2;c[d+96>>2]=e;n=b[a+50>>1]|0;h=n<<16>>16==0;if(h)e=t<<16>>16!=0?2:0;else e=2;c[d+104>>2]=e;o=b[a+56>>1]|0;j=o<<16>>16==0;if(j)f=u<<16>>16!=0?2:0;else f=2;c[d+112>>2]=f;k=(b[a+58>>1]|0)==0;if(k)f=g<<16>>16!=0?2:0;else f=2;c[d+120>>2]=f;g=b[a+30>>1]|0;if(!(g<<16>>16))f=(b[l>>1]|0)!=0?2:0;else f=2;c[d+12>>2]=f;e=b[a+36>>1]|0;if(!(e<<16>>16))f=g<<16>>16!=0?2:0;else f=2;c[d+20>>2]=f;if(!(b[a+38>>1]|0))e=e<<16>>16!=0?2:0;else e=2;c[d+28>>2]=e;if(x)e=y<<16>>16!=0?2:0;else e=2;c[d+44>>2]=e;if(v)e=z<<16>>16!=0?2:0;else e=2;c[d+52>>2]=e;if(w)e=A<<16>>16!=0?2:0;else e=2;c[d+60>>2]=e;if(p)e=s<<16>>16!=0?2:0;else e=2;c[d+76>>2]=e;if(q)e=t<<16>>16!=0?2:0;else e=2;c[d+84>>2]=e;if(r)e=u<<16>>16!=0?2:0;else e=2;c[d+92>>2]=e;if(h)e=m<<16>>16!=0?2:0;else e=2;c[d+108>>2]=e;if(j)e=n<<16>>16!=0?2:0;else e=2;c[d+116>>2]=e;if(!k){y=2;z=d+124|0;c[z>>2]=y;i=B;return}y=o<<16>>16!=0?2:0;z=d+124|0;c[z>>2]=y;i=B;return}function wc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=i;u=c[f+4>>2]|0;v=c[f+8>>2]|0;if(e>>>0<4){l=d[(c[f>>2]|0)+(e+-1)>>0]|0;n=0-l|0;m=l+1|0;k=4;while(1){f=b+-2|0;s=d[f>>0]|0;t=b+-1|0;r=d[t>>0]|0;q=d[b>>0]|0;j=b+1|0;h=d[j>>0]|0;o=r-q|0;if((((o|0)>-1?o:0-o|0)>>>0>>0?(o=s-r|0,((o|0)>-1?o:0-o|0)>>>0>>0):0)?(o=h-q|0,((o|0)>-1?o:0-o|0)>>>0>>0):0){e=d[b+-3>>0]|0;p=d[b+2>>0]|0;o=e-r|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){a[f>>0]=(Oa(n,l,((r+1+q|0)>>>1)-(s<<1)+e>>1)|0)+s;f=m}else f=l;o=p-q|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){a[j>>0]=(Oa(n,l,((r+1+q|0)>>>1)-(h<<1)+p>>1)|0)+h;f=f+1|0}j=Oa(0-f|0,f,s+4-h+(q-r<<2)>>3)|0;o=a[3472+((q|512)-j)>>0]|0;a[t>>0]=a[3472+((r|512)+j)>>0]|0;a[b>>0]=o}k=k+-1|0;if(!k)break;else b=b+g|0}i=w;return}t=(u>>>2)+2|0;s=4;while(1){k=b+-2|0;q=d[k>>0]|0;l=b+-1|0;r=d[l>>0]|0;m=d[b>>0]|0;e=b+1|0;n=d[e>>0]|0;f=r-m|0;f=(f|0)>-1?f:0-f|0;do if((f>>>0>>0?(o=q-r|0,((o|0)>-1?o:0-o|0)>>>0>>0):0)?(o=n-m|0,((o|0)>-1?o:0-o|0)>>>0>>0):0){h=b+-3|0;o=d[h>>0]|0;j=b+2|0;p=d[j>>0]|0;if(f>>>0>>0){f=o-r|0;if(((f|0)>-1?f:0-f|0)>>>0>>0){f=r+q+m|0;a[l>>0]=(n+4+(f<<1)+o|0)>>>3;a[k>>0]=(f+2+o|0)>>>2;a[h>>0]=(f+4+(o*3|0)+((d[b+-4>>0]|0)<<1)|0)>>>3}else a[l>>0]=(r+2+(q<<1)+n|0)>>>2;o=p-m|0;if(((o|0)>-1?o:0-o|0)>>>0>>0){o=m+r+n|0;a[b>>0]=(q+4+(o<<1)+p|0)>>>3;a[e>>0]=(o+2+p|0)>>>2;a[j>>0]=(o+4+(p*3|0)+((d[b+3>>0]|0)<<1)|0)>>>3;break}}else a[l>>0]=(r+2+(q<<1)+n|0)>>>2;a[b>>0]=(q+2+m+(n<<1)|0)>>>2}while(0);s=s+-1|0;if(!s)break;else b=b+g|0}i=w;return}function xc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;A=i;u=d[(c[f>>2]|0)+(e+-1)>>0]|0;w=0-g|0;v=w<<1;t=f+4|0;o=f+8|0;q=Z(g,-3)|0;s=0-u|0;p=u+1|0;r=g<<1;n=4;while(1){e=b+v|0;k=b+w|0;j=b+g|0;f=a[j>>0]|0;l=d[k>>0]|0;m=d[b>>0]|0;h=l-m|0;if((((h|0)>-1?h:0-h|0)>>>0<(c[t>>2]|0)>>>0?(y=d[e>>0]|0,h=y-l|0,x=c[o>>2]|0,((h|0)>-1?h:0-h|0)>>>0>>0):0)?(z=f&255,f=z-m|0,((f|0)>-1?f:0-f|0)>>>0>>0):0){f=d[b+q>>0]|0;h=f-l|0;if(((h|0)>-1?h:0-h|0)>>>0>>0){a[e>>0]=(Oa(s,u,((l+1+m|0)>>>1)-(y<<1)+f>>1)|0)+y;e=c[o>>2]|0;f=p}else{e=x;f=u}h=d[b+r>>0]|0;B=h-m|0;if(((B|0)>-1?B:0-B|0)>>>0>>0){a[j>>0]=(Oa(s,u,((l+1+m|0)>>>1)-(z<<1)+h>>1)|0)+z;f=f+1|0}f=Oa(0-f|0,f,4-z+(m-l<<2)+y>>3)|0;e=a[3472+((m|512)-f)>>0]|0;a[k>>0]=a[3472+((l|512)+f)>>0]|0;a[b>>0]=e}n=n+-1|0;if(!n)break;else b=b+1|0}i=A;return} +function ya(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+15&-16;return b|0}function za(){return i|0}function Aa(a){a=a|0;i=a}function Ba(a,b){a=a|0;b=b|0;if(!m){m=a;n=b}}function Ca(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Da(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Ea(a){a=a|0;B=a}function Fa(){return B|0}function Ga(a,b,e,f){a=a|0;b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;k=i;g=d[8+b>>0]|0;j=d[64+b>>0]|0;b=c[120+(j*12|0)>>2]<>2]<>2]<>2]=Z(c[a>>2]|0,b)|0;a:do if(!(f&65436)){if(f&98){n=a+4|0;l=Z(c[n>>2]|0,h)|0;j=a+20|0;m=Z(c[j>>2]|0,b)|0;e=a+24|0;g=Z(c[e>>2]|0,h)|0;h=c[a>>2]|0;b=(l>>1)-g|0;g=l+(g>>1)|0;l=m+h+32|0;f=l+g>>6;c[a>>2]=f;m=h-m+32|0;h=m+b>>6;c[n>>2]=h;b=m-b>>6;c[a+8>>2]=b;g=l-g>>6;c[a+12>>2]=g;c[a+48>>2]=f;c[a+32>>2]=f;c[a+16>>2]=f;c[a+52>>2]=h;c[a+36>>2]=h;c[j>>2]=h;c[a+56>>2]=b;c[a+40>>2]=b;c[e>>2]=b;c[a+60>>2]=g;c[a+44>>2]=g;c[a+28>>2]=g;if((f+512|0)>>>0>1023|(h+512|0)>>>0>1023|(b+512|0)>>>0>1023|(g+512|0)>>>0>1023)g=1;else break;i=k;return g|0}g=(c[a>>2]|0)+32>>6;if((g+512|0)>>>0>1023){m=1;i=k;return m|0}else{c[a+60>>2]=g;c[a+56>>2]=g;c[a+52>>2]=g;c[a+48>>2]=g;c[a+44>>2]=g;c[a+40>>2]=g;c[a+36>>2]=g;c[a+32>>2]=g;c[a+28>>2]=g;c[a+24>>2]=g;c[a+20>>2]=g;c[a+16>>2]=g;c[a+12>>2]=g;c[a+8>>2]=g;c[a+4>>2]=g;c[a>>2]=g;break}}else{z=a+4|0;s=a+56|0;w=a+60|0;t=c[w>>2]|0;u=Z(c[z>>2]|0,h)|0;c[s>>2]=Z(c[s>>2]|0,h)|0;c[w>>2]=Z(t,g)|0;w=a+8|0;t=c[w>>2]|0;s=a+16|0;y=Z(c[a+20>>2]|0,b)|0;o=Z(c[s>>2]|0,g)|0;q=a+12|0;p=c[q>>2]|0;f=Z(c[a+32>>2]|0,h)|0;e=Z(c[a+24>>2]|0,h)|0;r=c[a+28>>2]|0;j=Z(c[a+48>>2]|0,g)|0;n=Z(c[a+36>>2]|0,h)|0;l=c[a+44>>2]|0;m=Z(c[a+40>>2]|0,g)|0;g=Z(c[a+52>>2]|0,h)|0;x=c[a>>2]|0;v=y+x|0;y=x-y|0;x=(u>>1)-e|0;u=(e>>1)+u|0;e=u+v|0;c[a>>2]=e;c[z>>2]=x+y;c[w>>2]=y-x;c[q>>2]=v-u;q=Z(h,r+t|0)|0;r=Z(t-r|0,h)|0;h=(o>>1)-j|0;o=(j>>1)+o|0;j=o+q|0;c[s>>2]=j;c[a+20>>2]=h+r;c[a+24>>2]=r-h;c[a+28>>2]=q-o;o=Z(b,l+p|0)|0;b=Z(p-l|0,b)|0;l=(f>>1)-g|0;f=(g>>1)+f|0;h=f+o|0;c[a+32>>2]=h;c[a+36>>2]=l+b;c[a+40>>2]=b-l;c[a+44>>2]=o-f;f=a+56|0;o=c[f>>2]|0;l=o+n|0;o=n-o|0;b=a+60|0;g=c[b>>2]|0;n=(m>>1)-g|0;m=(g>>1)+m|0;g=m+l|0;c[a+48>>2]=g;c[a+52>>2]=n+o;c[f>>2]=o-n;c[b>>2]=l-m;b=j;j=3;while(1){v=(b>>1)-g|0;g=(g>>1)+b|0;w=h+e+32|0;x=w+g>>6;c[a>>2]=x;b=e-h+32|0;y=b+v>>6;c[a+16>>2]=y;b=b-v>>6;c[a+32>>2]=b;g=w-g>>6;c[a+48>>2]=g;if((x+512|0)>>>0>1023|(y+512|0)>>>0>1023){g=1;b=14;break}if((b+512|0)>>>0>1023|(g+512|0)>>>0>1023){g=1;b=14;break}f=a+4|0;if(!j)break a;e=c[f>>2]|0;h=c[a+36>>2]|0;b=c[a+20>>2]|0;g=c[a+52>>2]|0;a=f;j=j+-1|0}if((b|0)==14){i=k;return g|0}}while(0);y=0;i=k;return y|0}function Ha(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;B=i;e=a[64+d>>0]|0;s=a[8+d>>0]|0;D=b+8|0;u=c[D>>2]|0;j=c[b+20>>2]|0;q=b+16|0;y=c[q>>2]|0;r=b+32|0;z=c[r>>2]|0;E=b+12|0;v=c[E>>2]|0;f=c[b+24>>2]|0;m=c[b+28>>2]|0;o=b+48|0;g=c[o>>2]|0;C=c[b+36>>2]|0;A=c[b+40>>2]|0;F=c[b+44>>2]|0;h=c[b+52>>2]|0;p=c[b>>2]|0;l=j+p|0;j=p-j|0;p=b+4|0;x=c[p>>2]|0;t=x-f|0;x=f+x|0;f=x+l|0;c[b>>2]=f;k=t+j|0;c[p>>2]=k;t=j-t|0;c[D>>2]=t;x=l-x|0;c[E>>2]=x;E=m+u|0;m=u-m|0;u=y-g|0;y=g+y|0;g=y+E|0;c[q>>2]=g;l=u+m|0;c[b+20>>2]=l;u=m-u|0;c[b+24>>2]=u;y=E-y|0;c[b+28>>2]=y;E=F+v|0;F=v-F|0;v=z-h|0;z=h+z|0;h=z+E|0;c[b+32>>2]=h;m=v+F|0;c[b+36>>2]=m;v=F-v|0;c[b+40>>2]=v;z=E-z|0;c[b+44>>2]=z;E=b+56|0;F=c[E>>2]|0;D=F+C|0;F=C-F|0;C=b+60|0;j=c[C>>2]|0;w=A-j|0;A=j+A|0;j=A+D|0;c[b+48>>2]=j;n=w+F|0;c[b+52>>2]=n;w=F-w|0;c[E>>2]=w;A=D-A|0;c[C>>2]=A;s=s&255;e=c[120+((e&255)*12|0)>>2]|0;if(d>>>0>11){d=e<>2]=Z(e+s|0,d)|0;c[q>>2]=Z(f+h|0,d)|0;c[r>>2]=Z(h-f|0,d)|0;c[o>>2]=Z(s-e|0,d)|0;r=m+k|0;e=k-m|0;q=l-n|0;s=n+l|0;c[p>>2]=Z(s+r|0,d)|0;c[b+20>>2]=Z(q+e|0,d)|0;c[b+36>>2]=Z(e-q|0,d)|0;c[b+52>>2]=Z(r-s|0,d)|0;s=v+t|0;t=t-v|0;v=u-w|0;w=w+u|0;c[b+8>>2]=Z(w+s|0,d)|0;c[b+24>>2]=Z(v+t|0,d)|0;c[b+40>>2]=Z(t-v|0,d)|0;c[b+56>>2]=Z(s-w|0,d)|0;w=z+x|0;v=x-z|0;x=y-A|0;y=A+y|0;c[b+12>>2]=Z(y+w|0,d)|0;c[b+28>>2]=Z(x+v|0,d)|0;c[b+44>>2]=Z(v-x|0,d)|0;c[b+60>>2]=Z(w-y|0,d)|0;i=B;return}else{C=(d+-6|0)>>>0<6?1:2;d=2-s|0;s=h+f|0;D=f-h|0;h=g-j|0;f=j+g|0;c[b>>2]=(Z(f+s|0,e)|0)+C>>d;c[q>>2]=(Z(h+D|0,e)|0)+C>>d;c[r>>2]=(Z(D-h|0,e)|0)+C>>d;c[o>>2]=(Z(s-f|0,e)|0)+C>>d;r=m+k|0;f=k-m|0;q=l-n|0;s=n+l|0;c[p>>2]=(Z(s+r|0,e)|0)+C>>d;c[b+20>>2]=(Z(q+f|0,e)|0)+C>>d;c[b+36>>2]=(Z(f-q|0,e)|0)+C>>d;c[b+52>>2]=(Z(r-s|0,e)|0)+C>>d;s=v+t|0;t=t-v|0;v=u-w|0;w=w+u|0;c[b+8>>2]=(Z(w+s|0,e)|0)+C>>d;c[b+24>>2]=(Z(v+t|0,e)|0)+C>>d;c[b+40>>2]=(Z(t-v|0,e)|0)+C>>d;c[b+56>>2]=(Z(s-w|0,e)|0)+C>>d;w=z+x|0;v=x-z|0;x=y-A|0;y=A+y|0;c[b+12>>2]=(Z(y+w|0,e)|0)+C>>d;c[b+28>>2]=(Z(x+v|0,e)|0)+C>>d;c[b+44>>2]=(Z(v-x|0,e)|0)+C>>d;c[b+60>>2]=(Z(w-y|0,e)|0)+C>>d;i=B;return}}function Ia(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;e=c[120+((d[64+b>>0]|0)*12|0)>>2]|0;if(b>>>0>5){e=e<<(d[8+b>>0]|0)+-1;b=0}else b=1;k=c[a>>2]|0;g=a+8|0;h=c[g>>2]|0;m=h+k|0;h=k-h|0;k=a+4|0;j=c[k>>2]|0;l=a+12|0;f=c[l>>2]|0;i=j-f|0;j=f+j|0;c[a>>2]=(Z(j+m|0,e)|0)>>b;c[k>>2]=(Z(m-j|0,e)|0)>>b;c[g>>2]=(Z(i+h|0,e)|0)>>b;c[l>>2]=(Z(h-i|0,e)|0)>>b;l=a+16|0;i=c[l>>2]|0;h=a+24|0;g=c[h>>2]|0;k=g+i|0;g=i-g|0;i=a+20|0;j=c[i>>2]|0;a=a+28|0;m=c[a>>2]|0;f=j-m|0;j=m+j|0;c[l>>2]=(Z(j+k|0,e)|0)>>b;c[i>>2]=(Z(k-j|0,e)|0)>>b;c[h>>2]=(Z(f+g|0,e)|0)>>b;c[a>>2]=(Z(g-f|0,e)|0)>>b;return}function Ja(a,b){a=a|0;b=b|0;var c=0,d=0;d=i;b=1<>>1}while((c|0)!=0&(c&a|0)==0);i=d;return b|0}function Ka(a){a=a|0;var b=0,d=0;d=i;b=8-(c[a+8>>2]|0)|0;a=jb(a,b)|0;if((a|0)==-1){a=1;i=d;return a|0}a=(a|0)!=(c[400+(b+-1<<2)>>2]|0)&1;i=d;return a|0}function La(a){a=a|0;var b=0,d=0,e=0,f=0;d=i;f=c[a+12>>2]<<3;e=c[a+16>>2]|0;b=f-e|0;if((f|0)==(e|0)){a=0;i=d;return a|0}if(b>>>0>8){a=1;i=d;return a|0}else{a=((kb(a)|0)>>>(32-b|0)|0)!=(1<>2]|0;do{d=d+1|0;if(d>>>0>=b>>>0)break}while((c[a+(d<<2)>>2]|0)!=(e|0));i=f;return ((d|0)==(b|0)?0:d)|0}function Na(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=c[a+4>>2]|0;f=(b>>>0)%(e>>>0)|0;d=b-f|0;b=Z(c[a+8>>2]|0,e)|0;e=c[a>>2]|0;c[a+12>>2]=e+((d<<8)+(f<<4));d=(f<<3)+(b<<8)+(d<<6)|0;c[a+16>>2]=e+d;c[a+20>>2]=e+(d+(b<<6));return}function Oa(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)>=(a|0))a=(c|0)>(b|0)?b:c;return a|0}function Pa(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=i;a:do if(((e>>>0>3?(a[b>>0]|0)==0:0)?(a[b+1>>0]|0)==0:0)?(h=a[b+2>>0]|0,(h&255)<2):0){b:do if((e|0)!=3){p=-3;q=3;k=b+3|0;j=2;while(1){if(h<<24>>24)if(h<<24>>24==1&j>>>0>1){o=q;h=0;m=0;l=0;break}else j=0;else j=j+1|0;l=q+1|0;if((l|0)==(e|0))break b;h=a[k>>0]|0;p=~q;q=l;k=k+1|0}while(1){r=a[k>>0]|0;n=o+1|0;j=r<<24>>24!=0;l=(j&1^1)+l|0;h=r<<24>>24==3&(l|0)==2?1:h;if(r<<24>>24==1&l>>>0>1){r=14;break}if(j){m=l>>>0>2?1:m;l=0}if((n|0)==(e|0)){r=18;break}else{o=n;k=k+1|0}}if((r|0)==14){n=p+o-l|0;c[f+12>>2]=n;j=q;l=l-(l>>>0<3?l:3)|0;break a}else if((r|0)==18){n=p+e-l|0;c[f+12>>2]=n;j=q;break a}}while(0);c[g>>2]=e;q=1;i=s;return q|0}else r=19;while(0);if((r|0)==19){c[f+12>>2]=e;n=e;h=1;j=0;m=0;l=0}k=b+j|0;c[f>>2]=k;c[f+4>>2]=k;c[f+8>>2]=0;c[f+16>>2]=0;o=f+12|0;c[g>>2]=l+j+n;if(m){q=1;i=s;return q|0}if(!h){q=0;i=s;return q|0}l=c[o>>2]|0;h=k;m=k;j=0;c:while(1){while(1){q=l;l=l+-1|0;if(!q){r=31;break c}k=a[h>>0]|0;if((j|0)!=2)break;if(k<<24>>24!=3){r=29;break}if(!l){h=1;r=32;break c}h=h+1|0;if((d[h>>0]|0)>3){h=1;r=32;break c}else j=0}if((r|0)==29){r=0;if((k&255)<3){h=1;r=32;break}else j=2}a[m>>0]=k;h=h+1|0;m=m+1|0;j=k<<24>>24==0?j+1|0:0}if((r|0)==31){c[o>>2]=m-h+(c[o>>2]|0);q=0;i=s;return q|0}else if((r|0)==32){i=s;return h|0}return 0}function Qa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;i=i+16|0;n=o;id(b,0,92);f=jb(a,8)|0;a:do if((((f|0)!=-1?(c[b>>2]=f,jb(a,1)|0,jb(a,1)|0,(jb(a,1)|0)!=-1):0)?(jb(a,5)|0)!=-1:0)?(e=jb(a,8)|0,(e|0)!=-1):0){m=b+4|0;c[m>>2]=e;f=b+8|0;d=nb(a,f)|0;if(!d)if((c[f>>2]|0)>>>0<=31){d=nb(a,n)|0;if(!d){f=c[n>>2]|0;if(f>>>0<=12){c[b+12>>2]=1<>2]|0;if(f>>>0<=2){c[b+16>>2]=f;b:do if(!f){d=nb(a,n)|0;if(d)break a;f=c[n>>2]|0;if(f>>>0>12){d=1;break a}c[b+20>>2]=1<>2]=(f|0)==1&1;d=ob(a,b+28|0)|0;if(d)break a;d=ob(a,b+32|0)|0;if(d)break a;h=b+36|0;d=nb(a,h)|0;if(d)break a;f=c[h>>2]|0;if(f>>>0>255){d=1;break a}if(!f){c[b+40>>2]=0;break}f=fd(f<<2)|0;g=b+40|0;c[g>>2]=f;if(!f){d=65535;break a}if(c[h>>2]|0){e=0;while(1){d=ob(a,f+(e<<2)|0)|0;e=e+1|0;if(d)break a;if(e>>>0>=(c[h>>2]|0)>>>0)break b;f=c[g>>2]|0}}}while(0);l=b+44|0;d=nb(a,l)|0;if(!d)if((c[l>>2]|0)>>>0<=16?(k=jb(a,1)|0,(k|0)!=-1):0){c[b+48>>2]=(k|0)==1&1;d=nb(a,n)|0;if(!d){e=b+52|0;c[e>>2]=(c[n>>2]|0)+1;d=nb(a,n)|0;if(!d){k=b+56|0;c[k>>2]=(c[n>>2]|0)+1;h=jb(a,1)|0;if((!((h|0)==0|(h|0)==-1)?(jb(a,1)|0)!=-1:0)?(j=jb(a,1)|0,(j|0)!=-1):0){j=(j|0)==1;c[b+60>>2]=j&1;if(j){j=b+64|0;d=nb(a,j)|0;if(d)break;f=b+68|0;d=nb(a,f)|0;if(d)break;h=b+72|0;d=nb(a,h)|0;if(d)break;g=b+76|0;d=nb(a,g)|0;if(d)break;e=c[e>>2]|0;if((c[j>>2]|0)>((e<<3)+~c[f>>2]|0)){d=1;break}f=c[k>>2]|0;if((c[h>>2]|0)>((f<<3)+~c[g>>2]|0)){d=1;break}}else{e=c[e>>2]|0;f=c[k>>2]|0}d=Z(f,e)|0;do switch(c[m>>2]|0){case 11:{f=396;e=345600;g=58;break}case 12:{f=396;e=912384;g=58;break}case 13:{f=396;e=912384;g=58;break}case 20:{f=396;e=912384;g=58;break}case 21:{f=792;e=1824768;g=58;break}case 22:{f=1620;e=3110400;g=58;break}case 30:{f=1620;e=3110400;g=58;break}case 31:{f=3600;e=6912e3;g=58;break}case 32:{f=5120;e=7864320;g=58;break}case 40:{f=8192;e=12582912;g=58;break}case 41:{f=8192;e=12582912;g=58;break}case 42:{f=8704;e=13369344;g=58;break}case 50:{f=22080;e=42393600;g=58;break}case 51:{f=36864;e=70778880;g=58;break}case 10:{f=99;e=152064;g=58;break}default:g=60}while(0);do if((g|0)==58){if(f>>>0>>0){g=60;break}e=(e>>>0)/((d*384|0)>>>0)|0;e=e>>>0<16?e:16;c[n>>2]=e;f=c[l>>2]|0;if(f>>>0>e>>>0){e=f;g=61}}while(0);if((g|0)==60){c[n>>2]=2147483647;e=c[l>>2]|0;g=61}if((g|0)==61)c[n>>2]=e;g=b+88|0;c[g>>2]=e;e=jb(a,1)|0;if((e|0)==-1){d=1;break}n=(e|0)==1;c[b+80>>2]=n&1;do if(n){e=fd(952)|0;f=b+84|0;c[f>>2]=e;if(!e){d=65535;break a}d=Ec(a,e)|0;if(d)break a;d=c[f>>2]|0;if(!(c[d+920>>2]|0))break;e=c[d+948>>2]|0;if((c[d+944>>2]|0)>>>0>e>>>0){d=1;break a}if(e>>>0<(c[l>>2]|0)>>>0){d=1;break a}if(e>>>0>(c[g>>2]|0)>>>0){d=1;break a}c[g>>2]=(e|0)==0?1:e}while(0);Ka(a)|0;d=0}else d=1}}}else d=1}else d=1}}else d=1}}else d=1}else d=1;while(0);i=o;return d|0}function Ra(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;j=i;if((c[a>>2]|0)!=(c[b>>2]|0)){d=1;i=j;return d|0}if((c[a+4>>2]|0)!=(c[b+4>>2]|0)){d=1;i=j;return d|0}if((c[a+12>>2]|0)!=(c[b+12>>2]|0)){d=1;i=j;return d|0}d=c[a+16>>2]|0;if((d|0)!=(c[b+16>>2]|0)){d=1;i=j;return d|0}if((c[a+44>>2]|0)!=(c[b+44>>2]|0)){d=1;i=j;return d|0}if((c[a+48>>2]|0)!=(c[b+48>>2]|0)){d=1;i=j;return d|0}if((c[a+52>>2]|0)!=(c[b+52>>2]|0)){d=1;i=j;return d|0}if((c[a+56>>2]|0)!=(c[b+56>>2]|0)){d=1;i=j;return d|0}h=c[a+60>>2]|0;if((h|0)!=(c[b+60>>2]|0)){d=1;i=j;return d|0}if((c[a+80>>2]|0)!=(c[b+80>>2]|0)){d=1;i=j;return d|0}a:do if(!d){if((c[a+20>>2]|0)!=(c[b+20>>2]|0)){d=1;i=j;return d|0}}else if((d|0)==1){if((c[a+24>>2]|0)!=(c[b+24>>2]|0)){d=1;i=j;return d|0}if((c[a+28>>2]|0)!=(c[b+28>>2]|0)){d=1;i=j;return d|0}if((c[a+32>>2]|0)!=(c[b+32>>2]|0)){d=1;i=j;return d|0}d=c[a+36>>2]|0;if((d|0)!=(c[b+36>>2]|0)){d=1;i=j;return d|0}if(d){e=c[a+40>>2]|0;f=c[b+40>>2]|0;g=0;while(1){if((c[e+(g<<2)>>2]|0)!=(c[f+(g<<2)>>2]|0)){d=1;break}g=g+1|0;if(g>>>0>=d>>>0)break a}i=j;return d|0}}while(0);if(h){if((c[a+64>>2]|0)!=(c[b+64>>2]|0)){d=1;i=j;return d|0}if((c[a+68>>2]|0)!=(c[b+68>>2]|0)){d=1;i=j;return d|0}if((c[a+72>>2]|0)!=(c[b+72>>2]|0)){d=1;i=j;return d|0}if((c[a+76>>2]|0)!=(c[b+76>>2]|0)){d=1;i=j;return d|0}}d=0;i=j;return d|0}function Sa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;i=i+16|0;j=l+4|0;k=l;id(b,0,72);d=nb(a,b)|0;if(d){i=l;return d|0}if((c[b>>2]|0)>>>0>255){d=1;i=l;return d|0}e=b+4|0;d=nb(a,e)|0;if(d){i=l;return d|0}if((c[e>>2]|0)>>>0>31){d=1;i=l;return d|0}if(jb(a,1)|0){d=1;i=l;return d|0}d=jb(a,1)|0;if((d|0)==-1){d=1;i=l;return d|0}c[b+8>>2]=(d|0)==1&1;d=nb(a,j)|0;if(d){i=l;return d|0}d=(c[j>>2]|0)+1|0;h=b+12|0;c[h>>2]=d;if(d>>>0>8){d=1;i=l;return d|0}a:do if(d>>>0>1){d=b+16|0;e=nb(a,d)|0;if(e){d=e;i=l;return d|0}d=c[d>>2]|0;if(d>>>0>6){d=1;i=l;return d|0}switch(d|0){case 5:case 4:case 3:{d=jb(a,1)|0;if((d|0)==-1){d=1;i=l;return d|0}c[b+32>>2]=(d|0)==1&1;d=nb(a,j)|0;if(!d){c[b+36>>2]=(c[j>>2]|0)+1;break a}else{i=l;return d|0}}case 0:{d=fd(c[h>>2]<<2)|0;f=b+20|0;c[f>>2]=d;if(!d){d=65535;i=l;return d|0}if(!(c[h>>2]|0))break a;else e=0;while(1){d=nb(a,j)|0;if(d)break;c[(c[f>>2]|0)+(e<<2)>>2]=(c[j>>2]|0)+1;e=e+1|0;if(e>>>0>=(c[h>>2]|0)>>>0)break a}i=l;return d|0}case 2:{e=b+24|0;c[e>>2]=fd((c[h>>2]<<2)+-4|0)|0;d=fd((c[h>>2]<<2)+-4|0)|0;g=b+28|0;c[g>>2]=d;if((c[e>>2]|0)==0|(d|0)==0){d=65535;i=l;return d|0}if((c[h>>2]|0)==1)break a;else f=0;while(1){d=nb(a,j)|0;if(d){e=46;break}c[(c[e>>2]|0)+(f<<2)>>2]=c[j>>2];d=nb(a,j)|0;if(d){e=46;break}c[(c[g>>2]|0)+(f<<2)>>2]=c[j>>2];f=f+1|0;if(f>>>0>=((c[h>>2]|0)+-1|0)>>>0)break a}if((e|0)==46){i=l;return d|0}break}case 6:{d=nb(a,j)|0;if(d){i=l;return d|0}e=(c[j>>2]|0)+1|0;d=b+40|0;c[d>>2]=e;e=fd(e<<2)|0;g=b+44|0;c[g>>2]=e;if(!e){d=65535;i=l;return d|0}f=c[432+((c[h>>2]|0)+-1<<2)>>2]|0;if(!(c[d>>2]|0))break a;else e=0;while(1){m=jb(a,f)|0;c[(c[g>>2]|0)+(e<<2)>>2]=m;e=e+1|0;if(m>>>0>=(c[h>>2]|0)>>>0){d=1;break}if(e>>>0>=(c[d>>2]|0)>>>0)break a}i=l;return d|0}default:break a}}while(0);d=nb(a,j)|0;if(d){a=d;i=l;return a|0}d=c[j>>2]|0;if(d>>>0>31){a=1;i=l;return a|0}c[b+48>>2]=d+1;d=nb(a,j)|0;if(d){a=d;i=l;return a|0}if((c[j>>2]|0)>>>0>31){a=1;i=l;return a|0}if(jb(a,1)|0){a=1;i=l;return a|0}if((jb(a,2)|0)>>>0>2){a=1;i=l;return a|0}d=ob(a,k)|0;if(d){a=d;i=l;return a|0}d=(c[k>>2]|0)+26|0;if(d>>>0>51){a=1;i=l;return a|0}c[b+52>>2]=d;d=ob(a,k)|0;if(d){a=d;i=l;return a|0}if(((c[k>>2]|0)+26|0)>>>0>51){a=1;i=l;return a|0}d=ob(a,k)|0;if(d){a=d;i=l;return a|0}d=c[k>>2]|0;if((d+12|0)>>>0>24){a=1;i=l;return a|0}c[b+56>>2]=d;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+60>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+64>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){a=1;i=l;return a|0}c[b+68>>2]=(d|0)==1&1;Ka(a)|0;a=0;i=l;return a|0}function Ta(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=i;i=i+32|0;s=w+20|0;q=w+16|0;o=w+12|0;l=w+8|0;v=w+4|0;t=w;id(b,0,988);u=Z(c[d+56>>2]|0,c[d+52>>2]|0)|0;k=nb(a,v)|0;if(k){f=k;i=w;return f|0}n=c[v>>2]|0;c[b>>2]=n;if(n>>>0>=u>>>0){f=1;i=w;return f|0}k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;m=b+4|0;c[m>>2]=k;if((k|0)==5|(k|0)==0)j=5;else if(!((k|0)==7|(k|0)==2)){f=1;i=w;return f|0}if((j|0)==5){if((c[f>>2]|0)==5){f=1;i=w;return f|0}if(!(c[d+44>>2]|0)){f=1;i=w;return f|0}}k=nb(a,v)|0;if(k){f=k;i=w;return f|0}n=c[v>>2]|0;c[b+8>>2]=n;if((n|0)!=(c[e>>2]|0)){f=1;i=w;return f|0}n=d+12|0;k=c[n>>2]|0;j=0;while(1)if(!(k>>>j))break;else j=j+1|0;k=jb(a,j+-1|0)|0;if((k|0)==-1){f=1;i=w;return f|0}j=(c[f>>2]|0)==5;if(j&(k|0)!=0){f=1;i=w;return f|0}c[b+12>>2]=k;if(j){k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;c[b+16>>2]=k;if(k>>>0>65535){f=1;i=w;return f|0}}g=d+16|0;k=c[g>>2]|0;if(!k){h=d+20|0;k=c[h>>2]|0;j=0;while(1)if(!(k>>>j))break;else j=j+1|0;k=jb(a,j+-1|0)|0;if((k|0)==-1){f=1;i=w;return f|0}j=b+20|0;c[j>>2]=k;do if(c[e+8>>2]|0){k=ob(a,t)|0;if(!k){c[b+24>>2]=c[t>>2];break}else{f=k;i=w;return f|0}}while(0);if((c[f>>2]|0)==5){k=c[j>>2]|0;if(k>>>0>(c[h>>2]|0)>>>1>>>0){f=1;i=w;return f|0}j=c[b+24>>2]|0;if((k|0)!=(((j|0)>0?0:0-j|0)|0)){f=1;i=w;return f|0}}k=c[g>>2]|0}if((k|0)==1?(c[d+24>>2]|0)==0:0){k=ob(a,t)|0;if(k){f=k;i=w;return f|0}k=b+28|0;c[k>>2]=c[t>>2];do if(c[e+8>>2]|0){j=ob(a,t)|0;if(!j){c[b+32>>2]=c[t>>2];break}else{f=j;i=w;return f|0}}while(0);if((c[f>>2]|0)==5?(j=c[k>>2]|0,k=(c[d+32>>2]|0)+j+(c[b+32>>2]|0)|0,(((j|0)<(k|0)?j:k)|0)!=0):0){f=1;i=w;return f|0}}if(c[e+68>>2]|0){k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;c[b+36>>2]=k;if(k>>>0>127){f=1;i=w;return f|0}}k=c[m>>2]|0;if((k|0)==5|(k|0)==0){k=jb(a,1)|0;if((k|0)==-1){f=1;i=w;return f|0}c[b+40>>2]=k;do if(!k){k=c[e+48>>2]|0;if(k>>>0>16){f=1;i=w;return f|0}else{c[b+44>>2]=k;break}}else{k=nb(a,v)|0;if(k){f=k;i=w;return f|0}k=c[v>>2]|0;if(k>>>0>15){f=1;i=w;return f|0}else{c[b+44>>2]=k+1;break}}while(0);k=c[m>>2]|0}do if((k|0)==5|(k|0)==0){g=c[b+44>>2]|0;j=c[n>>2]|0;k=jb(a,1)|0;if((k|0)==-1){f=1;i=w;return f|0}c[b+68>>2]=k;if(k){h=0;a:while(1){if(h>>>0>g>>>0){r=1;j=110;break}k=nb(a,l)|0;if(k){r=k;j=110;break}k=c[l>>2]|0;if(k>>>0>3){r=1;j=110;break}c[b+(h*12|0)+72>>2]=k;do if(k>>>0<2){k=nb(a,o)|0;if(k){r=k;j=110;break a}k=c[o>>2]|0;if(k>>>0>=j>>>0){r=1;j=110;break a}c[b+(h*12|0)+76>>2]=k+1}else{if((k|0)!=2)break;k=nb(a,o)|0;if(k){r=k;j=110;break a}c[b+(h*12|0)+80>>2]=c[o>>2]}while(0);if((c[l>>2]|0)==3){j=61;break}else h=h+1|0}if((j|0)==61){if(!h)r=1;else break;i=w;return r|0}else if((j|0)==110){i=w;return r|0}}}while(0);do if(c[f+4>>2]|0){n=c[d+44>>2]|0;f=(c[f>>2]|0)==5;k=jb(a,1)|0;j=(k|0)==-1;if(f){if(j){f=1;i=w;return f|0}c[b+276>>2]=k;g=jb(a,1)|0;if((g|0)==-1){f=1;i=w;return f|0}c[b+280>>2]=g;if((n|0)!=0|(g|0)==0)break;else r=1;i=w;return r|0}if(j){f=1;i=w;return f|0}c[b+284>>2]=k;if(k){j=(n<<1)+2|0;h=0;d=0;g=0;l=0;m=0;while(1){if(h>>>0>j>>>0){r=1;j=110;break}k=nb(a,q)|0;if(k){r=k;j=110;break}k=c[q>>2]|0;if(k>>>0>6){r=1;j=110;break}c[b+(h*20|0)+288>>2]=k;if((k&-3|0)==1){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+292>>2]=(c[s>>2]|0)+1;k=c[q>>2]|0}if((k|0)==2){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+296>>2]=c[s>>2];k=c[q>>2]|0}if((k|0)==3|(k|0)==6){k=nb(a,s)|0;if(k){r=k;j=110;break}c[b+(h*20|0)+300>>2]=c[s>>2];k=c[q>>2]|0}if((k|0)==4){k=nb(a,s)|0;if(k){r=k;j=110;break}k=c[s>>2]|0;if(k>>>0>n>>>0){r=1;j=110;break}if(!k)c[b+(h*20|0)+304>>2]=65535;else c[b+(h*20|0)+304>>2]=k+-1;k=c[q>>2]|0;p=g+1|0}else p=g;l=((k|0)==5&1)+l|0;d=((k|0)!=0&k>>>0<4&1)+d|0;m=((k|0)==6&1)+m|0;if(!k){j=90;break}else{h=h+1|0;g=p}}if((j|0)==90){if(p>>>0>1|l>>>0>1|m>>>0>1){f=1;i=w;return f|0}if((d|0)!=0&(l|0)!=0)r=1;else break;i=w;return r|0}else if((j|0)==110){i=w;return r|0}}}while(0);g=ob(a,t)|0;if(g){f=g;i=w;return f|0}f=c[t>>2]|0;c[b+48>>2]=f;f=f+(c[e+52>>2]|0)|0;c[t>>2]=f;if(f>>>0>51){f=1;i=w;return f|0}do if(c[e+60>>2]|0){g=nb(a,v)|0;if(g){f=g;i=w;return f|0}g=c[v>>2]|0;c[b+52>>2]=g;if(g>>>0>2){f=1;i=w;return f|0}if((g|0)==1)break;g=ob(a,t)|0;if(g){f=g;i=w;return f|0}g=c[t>>2]|0;if((g+6|0)>>>0>12){f=1;i=w;return f|0}c[b+56>>2]=g<<1;g=ob(a,t)|0;if(g){f=g;i=w;return f|0}g=c[t>>2]|0;if((g+6|0)>>>0>12){f=1;i=w;return f|0}else{c[b+60>>2]=g<<1;break}}while(0);do if((c[e+12>>2]|0)>>>0>1?((c[e+16>>2]|0)+-3|0)>>>0<3:0){k=e+36|0;j=c[k>>2]|0;j=(((u>>>0)%(j>>>0)|0|0)==0?1:2)+((u>>>0)/(j>>>0)|0)|0;h=0;while(1){g=h+1|0;if(!(-1<>2]=g;if((g|0)==-1){f=1;i=w;return f|0}c[b+64>>2]=g;f=c[k>>2]|0;if(g>>>0>(((u+-1+f|0)>>>0)/(f>>>0)|0)>>>0)r=1;else break;i=w;return r|0}while(0);f=0;i=w;return f|0}function Ua(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;i=i+32|0;e=f+20|0;d=f;c[d+0>>2]=c[a+0>>2];c[d+4>>2]=c[a+4>>2];c[d+8>>2]=c[a+8>>2];c[d+12>>2]=c[a+12>>2];c[d+16>>2]=c[a+16>>2];a=nb(d,e)|0;if(!a){a=nb(d,e)|0;if(!a){a=nb(d,e)|0;if(!a){a=c[e>>2]|0;if(a>>>0>255)a=1;else{c[b>>2]=a;a=0}}}}i=f;return a|0}function Va(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+32|0;e=g+20|0;f=g;c[f+0>>2]=c[a+0>>2];c[f+4>>2]=c[a+4>>2];c[f+8>>2]=c[a+8>>2];c[f+12>>2]=c[a+12>>2];c[f+16>>2]=c[a+16>>2];a=nb(f,e)|0;if(a){i=g;return a|0}a=nb(f,e)|0;if(a){i=g;return a|0}a=nb(f,e)|0;if(!a)a=0;else{i=g;return a|0}while(1)if(!(b>>>a))break;else a=a+1|0;a=jb(f,a+-1|0)|0;if((a|0)==-1){a=1;i=g;return a|0}c[d>>2]=a;a=0;i=g;return a|0}function Wa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;h=i;i=i+32|0;f=h+20|0;g=h;if((d|0)!=5){d=1;i=h;return d|0};c[g+0>>2]=c[a+0>>2];c[g+4>>2]=c[a+4>>2];c[g+8>>2]=c[a+8>>2];c[g+12>>2]=c[a+12>>2];c[g+16>>2]=c[a+16>>2];d=nb(g,f)|0;if(d){i=h;return d|0}d=nb(g,f)|0;if(d){i=h;return d|0}d=nb(g,f)|0;if(!d)d=0;else{i=h;return d|0}while(1)if(!(b>>>d))break;else d=d+1|0;if((jb(g,d+-1|0)|0)==-1){d=1;i=h;return d|0}d=nb(g,e)|0;i=h;return d|0}function Xa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;k=i;i=i+32|0;h=k+20|0;j=k;c[j+0>>2]=c[a+0>>2];c[j+4>>2]=c[a+4>>2];c[j+8>>2]=c[a+8>>2];c[j+12>>2]=c[a+12>>2];c[j+16>>2]=c[a+16>>2];a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=c[b+12>>2]|0;f=0;while(1)if(!(a>>>f))break;else f=f+1|0;if((jb(j,f+-1|0)|0)==-1){f=1;i=k;return f|0}if((d|0)==5?(g=nb(j,h)|0,(g|0)!=0):0){f=g;i=k;return f|0}f=c[b+20>>2]|0;a=0;while(1)if(!(f>>>a))break;else a=a+1|0;f=jb(j,a+-1|0)|0;if((f|0)==-1){f=1;i=k;return f|0}c[e>>2]=f;f=0;i=k;return f|0}function Ya(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;k=i;i=i+32|0;h=k+20|0;j=k;c[j+0>>2]=c[a+0>>2];c[j+4>>2]=c[a+4>>2];c[j+8>>2]=c[a+8>>2];c[j+12>>2]=c[a+12>>2];c[j+16>>2]=c[a+16>>2];a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=nb(j,h)|0;if(a){f=a;i=k;return f|0}a=c[b+12>>2]|0;f=0;while(1)if(!(a>>>f))break;else f=f+1|0;if((jb(j,f+-1|0)|0)==-1){f=1;i=k;return f|0}if((d|0)==5?(g=nb(j,h)|0,(g|0)!=0):0){f=g;i=k;return f|0}f=c[b+20>>2]|0;a=0;while(1)if(!(f>>>a))break;else a=a+1|0;if((jb(j,a+-1|0)|0)==-1){f=1;i=k;return f|0}f=ob(j,e)|0;i=k;return f|0}function Za(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0;m=i;i=i+32|0;j=m+20|0;l=m;c[l+0>>2]=c[a+0>>2];c[l+4>>2]=c[a+4>>2];c[l+8>>2]=c[a+8>>2];c[l+12>>2]=c[a+12>>2];c[l+16>>2]=c[a+16>>2];g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=nb(l,j)|0;if(g){l=g;i=m;return l|0}g=c[b+12>>2]|0;a=0;while(1)if(!(g>>>a))break;else a=a+1|0;if((jb(l,a+-1|0)|0)==-1){l=1;i=m;return l|0}if((d|0)==5?(h=nb(l,j)|0,(h|0)!=0):0){l=h;i=m;return l|0}g=ob(l,f)|0;if(g){l=g;i=m;return l|0}if((e|0)!=0?(k=ob(l,f+4|0)|0,(k|0)!=0):0){l=k;i=m;return l|0}l=0;i=m;return l|0}function _a(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;m=i;i=i+32|0;l=m+24|0;j=m+20|0;k=m;c[k+0>>2]=c[b+0>>2];c[k+4>>2]=c[b+4>>2];c[k+8>>2]=c[b+8>>2];c[k+12>>2]=c[b+12>>2];c[k+16>>2]=c[b+16>>2];f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}f=c[d+12>>2]|0;b=0;while(1)if(!(f>>>b))break;else b=b+1|0;if((jb(k,b+-1|0)|0)==-1){n=1;i=m;return n|0}f=nb(k,l)|0;if(f){n=f;i=m;return n|0}g=d+16|0;f=c[g>>2]|0;if(!f){b=c[d+20>>2]|0;f=0;while(1)if(!(b>>>f))break;else f=f+1|0;if((jb(k,f+-1|0)|0)==-1){n=1;i=m;return n|0}if((c[e+8>>2]|0)!=0?(h=ob(k,j)|0,(h|0)!=0):0){n=h;i=m;return n|0}f=c[g>>2]|0}if((f|0)==1?(c[d+24>>2]|0)==0:0){f=ob(k,j)|0;if(f){n=f;i=m;return n|0}if((c[e+8>>2]|0)!=0?(n=ob(k,j)|0,(n|0)!=0):0){i=m;return n|0}}if((c[e+68>>2]|0)!=0?(o=nb(k,l)|0,(o|0)!=0):0){n=o;i=m;return n|0}n=jb(k,1)|0;c[a>>2]=n;n=(n|0)==-1&1;i=m;return n|0}function $a(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;C=i;i=i+448|0;p=C+8|0;x=C+4|0;v=C;p=p+(0-p&15)|0;n=c[b+3376>>2]|0;j=c[e>>2]|0;c[x>>2]=0;y=b+1192|0;c[y>>2]=(c[y>>2]|0)+1;q=b+1200|0;c[q>>2]=0;o=b+12|0;c[v>>2]=(c[e+48>>2]|0)+(c[(c[o>>2]|0)+52>>2]|0);w=e+36|0;r=b+1212|0;s=e+52|0;t=e+56|0;u=e+60|0;z=e+4|0;l=e+44|0;h=b+1220|0;m=b+1172|0;B=b+1176|0;k=n+12|0;A=0;f=0;while(1){e=c[r>>2]|0;if((c[w>>2]|0)==0?(c[e+(j*216|0)+196>>2]|0)!=0:0){f=1;e=22;break}g=c[(c[o>>2]|0)+56>>2]|0;F=c[s>>2]|0;E=c[t>>2]|0;D=c[u>>2]|0;c[e+(j*216|0)+4>>2]=c[y>>2];c[e+(j*216|0)+8>>2]=F;c[e+(j*216|0)+12>>2]=E;c[e+(j*216|0)+16>>2]=D;c[e+(j*216|0)+24>>2]=g;e=c[z>>2]|0;if((e|0)!=2?!((e|0)==7|(f|0)!=0):0){f=nb(a,x)|0;if(f){e=22;break}e=c[x>>2]|0;if(e>>>0>((c[B>>2]|0)-j|0)>>>0){f=1;e=22;break}if(!e)f=0;else{id(k,0,164);c[n>>2]=0;f=1}}e=c[x>>2]|0;if(!e){f=bb(a,n,(c[r>>2]|0)+(j*216|0)|0,c[z>>2]|0,c[l>>2]|0)|0;if(!f)g=0;else{e=22;break}}else{c[x>>2]=e+-1;g=f}f=gb((c[r>>2]|0)+(j*216|0)|0,n,d,h,v,j,c[(c[o>>2]|0)+64>>2]|0,p)|0;if(f){e=22;break}A=((c[(c[r>>2]|0)+(j*216|0)+196>>2]|0)==1&1)+A|0;if(!(La(a)|0))e=(c[x>>2]|0)!=0;else e=1;f=c[z>>2]|0;if((f|0)==7|(f|0)==2)c[q>>2]=j;j=Ma(c[m>>2]|0,c[B>>2]|0,j)|0;if(!((j|0)!=0|e^1)){f=1;e=22;break}if(!e){e=20;break}else f=g}if((e|0)==20){e=b+1196|0;f=(c[e>>2]|0)+A|0;if(f>>>0>(c[B>>2]|0)>>>0){y=1;i=C;return y|0}c[e>>2]=f;y=0;i=C;return y|0}else if((e|0)==22){i=C;return f|0}return 0}function ab(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;h=c[a+1192>>2]|0;d=c[a+1200>>2]|0;j=a+1212|0;a:do if(!d)d=b;else{e=a+16|0;f=0;do{do{d=d+-1|0;if(d>>>0<=b>>>0)break a}while((c[(c[j>>2]|0)+(d*216|0)+4>>2]|0)!=(h|0));f=f+1|0;g=c[(c[e>>2]|0)+52>>2]|0}while(f>>>0<(g>>>0>10?g:10)>>>0)}while(0);g=a+1172|0;b=a+1176|0;while(1){e=c[j>>2]|0;if((c[e+(d*216|0)+4>>2]|0)!=(h|0)){d=11;break}f=e+(d*216|0)+196|0;e=c[f>>2]|0;if(!e){d=11;break}c[f>>2]=e+-1;d=Ma(c[g>>2]|0,c[b>>2]|0,d)|0;if(!d){d=11;break}}if((d|0)==11){i=k;return}}function bb(a,d,e,f,g){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;B=i;i=i+32|0;u=B+20|0;v=B+16|0;q=B+12|0;p=B+8|0;z=B+4|0;y=B;id(d,0,2088);l=nb(a,z)|0;m=c[z>>2]|0;do if((f|0)==2|(f|0)==7){m=m+6|0;if(m>>>0>31|(l|0)!=0){e=1;i=B;return e|0}else{c[d>>2]=m;o=m;break}}else{m=m+1|0;if(m>>>0>31|(l|0)!=0){e=1;i=B;return e|0}else{c[d>>2]=m;o=m;break}}while(0);a:do if((o|0)!=31){b:do if(o>>>0>=6){o=(o|0)!=6;p=o&1;if(!p){c[v>>2]=0;q=0;while(1){f=kb(a)|0;c[u>>2]=f;t=f>>>31;c[d+(q<<2)+12>>2]=t;if(!t){c[d+(q<<2)+76>>2]=f>>>28&7;m=f<<4;n=1}else{m=f<<1;n=0}f=q|1;t=m>>>31;c[d+(f<<2)+12>>2]=t;if(!t){c[d+(f<<2)+76>>2]=m>>>28&7;l=m<<4;n=n+1|0}else l=m<<1;m=f+1|0;t=l>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=l>>>28&7;m=l<<4;n=n+1|0}else m=l<<1;l=q|3;t=m>>>31;c[d+(l<<2)+12>>2]=t;if(!t){c[d+(l<<2)+76>>2]=m>>>28&7;f=m<<4;n=n+1|0}else f=m<<1;m=l+1|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=l+2|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=l+3|0;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;f=f<<4;n=n+1|0}else f=f<<1;m=q|7;t=f>>>31;c[d+(m<<2)+12>>2]=t;if(!t){c[d+(m<<2)+76>>2]=f>>>28&7;m=f<<4;n=n+1|0}else m=f<<1;c[u>>2]=m;if((lb(a,(n*3|0)+8|0)|0)==-1){w=1;t=68;break b}t=(c[v>>2]|0)+1|0;c[v>>2]=t;if((t|0)<2)q=q+8|0;else{t=52;break}}}else if((p|0)==1)t=52;if((t|0)==52){v=(nb(a,u)|0)!=0;l=c[u>>2]|0;if(v|l>>>0>3){w=1;t=68;break}c[d+140>>2]=l}if(o){v=c[d>>2]|0;s=v+-7|0;u=s>>>2;c[d+4>>2]=(s>>>0>11?u+268435453|0:u)<<4|(v>>>0>18?15:0)}else{x=p;t=70}}else{if((o|0)==0|(o|0)==1){r=v;s=u}else if(!((o|0)==3|(o|0)==2)){f=0;do{l=(nb(a,q)|0)!=0;m=c[q>>2]|0;if(l|m>>>0>3){n=1;t=96;break}c[d+(f<<2)+176>>2]=m;f=f+1|0}while(f>>>0<4);if((t|0)==96){i=B;return n|0}c:do if(g>>>0>1&(o|0)!=5){m=g>>>0>2&1;f=0;while(1){if(qb(a,q,m)|0){n=1;t=96;break}n=c[q>>2]|0;if(n>>>0>=g>>>0){n=1;t=96;break}c[d+(f<<2)+192>>2]=n;f=f+1|0;if(f>>>0>=4){h=0;break c}}if((t|0)==96){i=B;return n|0}}else h=0;while(0);d:while(1){n=c[d+(h<<2)+176>>2]|0;if(!n)n=0;else if((n|0)==2|(n|0)==1)n=1;else n=3;c[q>>2]=n;m=0;while(1){n=ob(a,p)|0;if(n){t=96;break d}b[d+(h<<4)+(m<<2)+208>>1]=c[p>>2];n=ob(a,p)|0;if(n){t=96;break d}b[d+(h<<4)+(m<<2)+210>>1]=c[p>>2];t=c[q>>2]|0;c[q>>2]=t+-1;if(!t)break;else m=m+1|0}h=h+1|0;if(h>>>0>=4){x=2;t=70;break b}}if((t|0)==96){i=B;return n|0}}else{r=v;s=u}if(g>>>0>1){if((o|0)==0|(o|0)==1)n=0;else if((o|0)==3|(o|0)==2)n=1;else n=3;l=g>>>0>2&1;f=0;while(1){if(qb(a,u,l)|0){w=1;t=68;break b}m=c[u>>2]|0;if(m>>>0>=g>>>0){w=1;t=68;break b}c[d+(f<<2)+144>>2]=m;if(!n)break;else{n=n+-1|0;f=f+1|0}}}if((o|0)==0|(o|0)==1){l=0;m=0}else if((o|0)==3|(o|0)==2){l=1;m=0}else{l=3;m=0}while(1){f=ob(a,v)|0;if(f){w=f;t=68;break b}b[d+(m<<2)+160>>1]=c[v>>2];f=ob(a,v)|0;if(f){w=f;t=68;break b}b[d+(m<<2)+162>>1]=c[v>>2];if(!l){x=2;t=70;break}else{l=l+-1|0;m=m+1|0}}}while(0);if((t|0)==68){e=w;i=B;return e|0}do if((t|0)==70){h=pb(a,z,(x|0)==0&1)|0;if(!h){z=c[z>>2]|0;c[d+4>>2]=z;if(!z)break a;else break}else{e=h;i=B;return e|0}}while(0);z=(ob(a,y)|0)!=0;h=c[y>>2]|0;if(z|(h|0)<-26|(h|0)>25){e=1;i=B;return e|0}c[d+8>>2]=h;l=c[d+4>>2]|0;o=d+272|0;e:do if((c[d>>2]|0)>>>0>=7){h=rb(a,d+1864|0,ib(e,0,o)|0,16)|0;if(!(h&15)){b[d+320>>1]=h>>>4&255;h=0;m=3;while(1){n=l>>>1;if(!(l&1))h=h+4|0;else{f=3;while(1){l=rb(a,d+(h<<6)+332|0,ib(e,h,o)|0,15)|0;c[d+(h<<2)+1992>>2]=l>>>15;if(l&15){j=l;break e}b[d+(h<<1)+272>>1]=l>>>4&255;h=h+1|0;if(!f)break;else f=f+-1|0}}if(!m){k=h;A=n;t=87;break}else{l=n;m=m+-1|0}}}else j=h}else{h=0;m=3;while(1){n=l>>>1;if(!(l&1))h=h+4|0;else{f=3;while(1){l=rb(a,d+(h<<6)+328|0,ib(e,h,o)|0,16)|0;c[d+(h<<2)+1992>>2]=l>>>16;if(l&15){j=l;break e}b[d+(h<<1)+272>>1]=l>>>4&255;h=h+1|0;if(!f)break;else f=f+-1|0}}if(!m){k=h;A=n;t=87;break}else{l=n;m=m+-1|0}}}while(0);f:do if((t|0)==87){if(A&3){j=rb(a,d+1928|0,-1,4)|0;if(j&15)break;b[d+322>>1]=j>>>4&255;j=rb(a,d+1944|0,-1,4)|0;if(j&15)break;b[d+324>>1]=j>>>4&255}if(!(A&2))j=0;else{h=7;while(1){j=rb(a,d+(k<<6)+332|0,ib(e,k,o)|0,15)|0;if(j&15)break f;b[d+(k<<1)+272>>1]=j>>>4&255;c[d+(k<<2)+1992>>2]=j>>>15;if(!h){j=0;break}else{k=k+1|0;h=h+-1|0}}}}while(0);c[a+16>>2]=((c[a+4>>2]|0)-(c[a>>2]|0)<<3)+(c[a+8>>2]|0);if(j){e=j;i=B;return e|0}}else{while(1){if(mb(a)|0)break;if(jb(a,1)|0){n=1;t=96;break}}if((t|0)==96){i=B;return n|0}k=0;j=d+328|0;while(1){h=jb(a,8)|0;c[z>>2]=h;if((h|0)==-1){n=1;break}c[j>>2]=h;k=k+1|0;if(k>>>0>=384)break a;else j=j+4|0}i=B;return n|0}while(0);e=0;i=B;return e|0}function cb(a){a=a|0;if(a>>>0<6)a=2;else a=(a|0)!=6&1;return a|0}function db(a){a=a|0;var b=0;b=i;if((a|0)==0|(a|0)==1)a=1;else if((a|0)==3|(a|0)==2)a=2;else a=4;i=b;return a|0}function eb(a){a=a|0;var b=0;b=i;if(!a)a=1;else if((a|0)==2|(a|0)==1)a=2;else a=4;i=b;return a|0}function fb(a){a=a|0;return a+1&3|0}function gb(d,e,f,g,h,j,k,l){d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=i;s=c[e>>2]|0;c[d>>2]=s;o=d+196|0;c[o>>2]=(c[o>>2]|0)+1;Na(f,j);if((s|0)==31){m=d+28|0;c[d+20>>2]=0;if((c[o>>2]|0)>>>0>1){b[m>>1]=16;b[d+30>>1]=16;b[d+32>>1]=16;b[d+34>>1]=16;b[d+36>>1]=16;b[d+38>>1]=16;b[d+40>>1]=16;b[d+42>>1]=16;b[d+44>>1]=16;b[d+46>>1]=16;b[d+48>>1]=16;b[d+50>>1]=16;b[d+52>>1]=16;b[d+54>>1]=16;b[d+56>>1]=16;b[d+58>>1]=16;b[d+60>>1]=16;b[d+62>>1]=16;b[d+64>>1]=16;b[d+66>>1]=16;b[d+68>>1]=16;b[d+70>>1]=16;b[d+72>>1]=16;b[d+74>>1]=16;t=0;i=v;return t|0}o=23;h=e+328|0;n=l;while(1){b[m>>1]=16;a[n>>0]=c[h>>2];a[n+1>>0]=c[h+4>>2];a[n+2>>0]=c[h+8>>2];a[n+3>>0]=c[h+12>>2];a[n+4>>0]=c[h+16>>2];a[n+5>>0]=c[h+20>>2];a[n+6>>0]=c[h+24>>2];a[n+7>>0]=c[h+28>>2];a[n+8>>0]=c[h+32>>2];a[n+9>>0]=c[h+36>>2];a[n+10>>0]=c[h+40>>2];a[n+11>>0]=c[h+44>>2];a[n+12>>0]=c[h+48>>2];a[n+13>>0]=c[h+52>>2];a[n+14>>0]=c[h+56>>2];a[n+15>>0]=c[h+60>>2];if(!o)break;else{o=o+-1|0;h=h+64|0;n=n+16|0;m=m+2|0}}sc(f,l);t=0;i=v;return t|0}m=d+28|0;if(s){hd(m,e+272|0,54);n=c[e+8>>2]|0;o=c[h>>2]|0;do if(n){o=o+n|0;c[h>>2]=o;if((o|0)<0){o=o+52|0;c[h>>2]=o;break}if((o|0)>51){o=o+-52|0;c[h>>2]=o}}while(0);r=d+20|0;c[r>>2]=o;n=e+328|0;h=e+1992|0;a:do if((c[d>>2]|0)>>>0<7){q=15;o=m;while(1){if(b[o>>1]|0){if(Ga(n,c[r>>2]|0,0,c[h>>2]|0)|0){m=1;break}}else c[n>>2]=16777215;n=n+64|0;o=o+2|0;h=h+4|0;if(!q)break a;else q=q+-1|0}i=v;return m|0}else{if(!(b[d+76>>1]|0)){q=464;p=15;o=m}else{Ha(e+1864|0,o);q=464;p=15;o=m}while(1){m=c[e+(c[q>>2]<<2)+1864>>2]|0;q=q+4|0;c[n>>2]=m;if((m|0)==0?(b[o>>1]|0)==0:0)c[n>>2]=16777215;else u=18;if((u|0)==18?(u=0,(Ga(n,c[r>>2]|0,1,c[h>>2]|0)|0)!=0):0){m=1;break}n=n+64|0;o=o+2|0;h=h+4|0;if(!p)break a;else p=p+-1|0}i=v;return m|0}while(0);q=c[192+((Oa(0,51,(c[d+24>>2]|0)+(c[r>>2]|0)|0)|0)<<2)>>2]|0;if((b[d+78>>1]|0)==0?(b[d+80>>1]|0)==0:0){p=e+1928|0;m=7}else{p=e+1928|0;Ia(p,q);m=7}while(1){r=c[p>>2]|0;p=p+4|0;c[n>>2]=r;if((r|0)==0?(b[o>>1]|0)==0:0)c[n>>2]=16777215;else u=31;if((u|0)==31?(u=0,(Ga(n,q,1,c[h>>2]|0)|0)!=0):0){m=1;u=39;break}if(!m)break;else{n=n+64|0;h=h+4|0;m=m+-1|0;o=o+2|0}}if((u|0)==39){i=v;return m|0}if(s>>>0>=6){o=Mb(d,e,f,j,k,l)|0;if(o){t=o;i=v;return t|0}}else u=37}else{id(m,0,54);c[d+20>>2]=c[h>>2];u=37}if((u|0)==37?(t=Sb(d,e,g,j,f,l)|0,(t|0)!=0):0){i=v;return t|0}t=0;i=v;return t|0}function hb(a){a=a|0;return a|0}function ib(d,e,f){d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0;k=i;l=vb(e)|0;g=wb(e)|0;h=a[l+4>>0]|0;j=a[g+4>>0]|0;g=(c[g>>2]|0)==4;if((c[l>>2]|0)==4){e=b[f+((h&255)<<1)>>1]|0;if(g){e=e+1+(b[f+((j&255)<<1)>>1]|0)>>1;i=k;return e|0}g=d+204|0;if(!(zb(d,c[g>>2]|0)|0)){i=k;return e|0}e=e+1+(b[(c[g>>2]|0)+((j&255)<<1)+28>>1]|0)>>1;i=k;return e|0}if(g){e=b[f+((j&255)<<1)>>1]|0;g=d+200|0;if(!(zb(d,c[g>>2]|0)|0)){i=k;return e|0}e=e+1+(b[(c[g>>2]|0)+((h&255)<<1)+28>>1]|0)>>1;i=k;return e|0}g=d+200|0;if(!(zb(d,c[g>>2]|0)|0)){h=0;f=0}else{h=b[(c[g>>2]|0)+((h&255)<<1)+28>>1]|0;f=1}g=d+204|0;if(!(zb(d,c[g>>2]|0)|0)){e=h;i=k;return e|0}e=b[(c[g>>2]|0)+((j&255)<<1)+28>>1]|0;if(!f){i=k;return e|0}e=h+1+e>>1;i=k;return e|0}function jb(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;n=a+4|0;j=c[n>>2]|0;m=c[a+12>>2]<<3;o=a+16|0;l=c[o>>2]|0;g=m-l|0;if((g|0)>31){e=a+8|0;g=c[e>>2]|0;f=(d[j+1>>0]|0)<<16|(d[j>>0]|0)<<24|(d[j+2>>0]|0)<<8|(d[j+3>>0]|0);if(!g)h=e;else{h=e;f=(d[j+4>>0]|0)>>>(8-g|0)|f<0){e=c[h>>2]|0;k=e+24|0;f=(d[j>>0]|0)<0){e=g;g=k;do{j=j+1|0;g=g+-8|0;f=(d[j>>0]|0)<0)}}else f=0}e=l+b|0;c[o>>2]=e;c[h>>2]=e&7;if(e>>>0>m>>>0){n=-1;i=p;return n|0}c[n>>2]=(c[a>>2]|0)+(e>>>3);n=f>>>(32-b|0);i=p;return n|0}function kb(a){a=a|0;var b=0,e=0,f=0,g=0,h=0;g=i;f=c[a+4>>2]|0;e=(c[a+12>>2]<<3)-(c[a+16>>2]|0)|0;if((e|0)>31){b=c[a+8>>2]|0;a=(d[f+1>>0]|0)<<16|(d[f>>0]|0)<<24|(d[f+2>>0]|0)<<8|(d[f+3>>0]|0);if(!b){b=a;i=g;return b|0}b=(d[f+4>>0]|0)>>>(8-b|0)|a<>2]|0;a=h+24|0;b=(d[f>>0]|0)<>0]|0)<0);i=g;return b|0}function lb(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;e=a+16|0;b=(c[e>>2]|0)+b|0;c[e>>2]=b;c[a+8>>2]=b&7;if(b>>>0>c[a+12>>2]<<3>>>0){b=-1;i=d;return b|0}c[a+4>>2]=(c[a>>2]|0)+(b>>>3);b=0;i=d;return b|0}function mb(a){a=a|0;return (c[a+8>>2]|0)==0|0}function nb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=i;d=kb(a)|0;do if((d|0)>=0){if(d>>>0>1073741823){if((lb(a,3)|0)==-1){d=1;break}c[b>>2]=(d>>>29&1)+1;d=0;break}if(d>>>0>536870911){if((lb(a,5)|0)==-1){d=1;break}c[b>>2]=(d>>>27&3)+3;d=0;break}if(d>>>0>268435455){if((lb(a,7)|0)==-1){d=1;break}c[b>>2]=(d>>>25&7)+7;d=0;break}d=Ja(d,28)|0;e=d+4|0;if((e|0)!=32){lb(a,d+5|0)|0;d=jb(a,e)|0;if((d|0)==-1){d=1;break}c[b>>2]=(1<>2]=0;lb(a,32)|0;if((jb(a,1)|0)==1?(f=kb(a)|0,(lb(a,32)|0)!=-1):0)if((f|0)==1){c[b>>2]=-1;d=1;break}else if(!f){c[b>>2]=-1;d=0;break}else{d=1;break}else d=1}else{lb(a,1)|0;c[b>>2]=0;d=0}while(0);i=g;return d|0}function ob(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;f=e;c[f>>2]=0;d=nb(a,f)|0;a=c[f>>2]|0;d=(d|0)==0;if((a|0)==-1)if(d)a=1;else{c[b>>2]=-2147483648;a=0}else if(d){d=(a+1|0)>>>1;c[b>>2]=(a&1|0)!=0?d:0-d|0;a=0}else a=1;i=e;return a|0}function pb(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0;g=i;i=i+16|0;f=g;if(nb(a,f)|0){f=1;i=g;return f|0}f=c[f>>2]|0;if(f>>>0>47){f=1;i=g;return f|0}c[b>>2]=d[((e|0)==0?576:528)+f>>0];f=0;i=g;return f|0}function qb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=i;if(!d){d=jb(a,1)|0;c[b>>2]=d;if((d|0)==-1)d=1;else{c[b>>2]=d^1;d=0}}else d=nb(a,b)|0;i=e;return d|0}function rb(a,b,f,g){a=a|0;b=b|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0;O=i;i=i+128|0;M=O+64|0;N=O;n=kb(a)|0;p=n>>>16;do if(f>>>0<2)if((n|0)>=0){if(n>>>0>201326591){o=e[1264+(n>>>26<<1)>>1]|0;k=25;break}if(n>>>0>16777215){o=e[1328+(n>>>22<<1)>>1]|0;k=25;break}if(n>>>0>2097151){o=e[1424+((n>>>18)+-8<<1)>>1]|0;k=25;break}else{o=e[1536+(p<<1)>>1]|0;k=25;break}}else q=1;else if(f>>>0<4){if((n|0)<0){q=(p&16384|0)!=0?2:2082;break}if(n>>>0>268435455){o=e[1600+(n>>>26<<1)>>1]|0;k=25;break}if(n>>>0>33554431){o=e[1664+(n>>>23<<1)>>1]|0;k=25;break}else{o=e[1728+(n>>>18<<1)>>1]|0;k=25;break}}else{if(f>>>0<8){f=n>>>26;if((f+-8|0)>>>0<56){o=e[1984+(f<<1)>>1]|0;k=25;break}o=e[2112+(n>>>22<<1)>>1]|0;k=25;break}if(f>>>0<17){o=e[2368+(n>>>26<<1)>>1]|0;k=25;break}f=n>>>29;if(f){o=e[2496+(f<<1)>>1]|0;k=25;break}o=e[2512+(n>>>24<<1)>>1]|0;k=25;break}while(0);if((k|0)==25)if(!o){C=1;i=O;return C|0}else q=o;o=q&31;f=n<>>11&31;if(I>>>0>g>>>0){C=1;i=O;return C|0}v=q>>>5&63;do if(I){if(!v)o=0;else{do if(p>>>0>>0)if((lb(a,o)|0)==-1){C=1;i=O;return C|0}else{p=32;f=kb(a)|0;break}while(0);n=f>>>(32-v|0);f=f<>2]=(o&n|0)!=0?-1:1;o=o>>>1;k=k+1|0}while((o|0)!=0);p=p-v|0;o=k}u=v>>>0<3;a:do if(o>>>0>>0){t=o;s=I>>>0>10&u&1;b:while(1){if(p>>>0<16){if((lb(a,32-p|0)|0)==-1){J=1;k=127;break}r=32;f=kb(a)|0}else r=p;do if((f|0)>=0)if(f>>>0<=1073741823)if(f>>>0<=536870911)if(f>>>0<=268435455)if(f>>>0<=134217727)if(f>>>0<=67108863)if(f>>>0<=33554431)if(f>>>0<=16777215)if(f>>>0<=8388607)if(f>>>0>4194303){H=9;k=59}else{if(f>>>0>2097151){H=10;k=59;break}if(f>>>0>1048575){H=11;k=59;break}if(f>>>0>524287){H=12;k=59;break}if(f>>>0>262143){H=13;k=59;break}if(f>>>0>131071){p=14;o=f<<15;n=r+-15|0;q=s;k=(s|0)!=0?s:4}else{if(f>>>0<65536){J=1;k=127;break b}p=15;o=f<<16;n=r+-16|0;q=(s|0)!=0?s:1;k=12}G=p<>>0>>0){if((lb(a,32-y|0)|0)==-1){J=1;k=127;break}o=32;f=kb(a)|0}else{o=y;f=B}E=o-x|0;F=f<>>(32-x|0))+G|0;C=z;D=w}s=(t|0)==(v|0)&u?A+2|0:A;o=(s+2|0)>>>1;n=D?1:C;c[M+(t<<2)>>2]=(s&1|0)==0?o:0-o|0;t=t+1|0;if(t>>>0>=I>>>0){l=E;m=F;break a}else{p=E;f=F;s=((o|0)>(3<>>0<6&1)+n|0}}if((k|0)==127){i=O;return J|0}}else{l=p;m=f}while(0);if(I>>>0>>0){do if(l>>>0<9)if((lb(a,32-l|0)|0)==-1){C=1;i=O;return C|0}else{l=32;m=kb(a)|0;break}while(0);k=m>>>23;c:do if((g|0)==4)if((m|0)>=0)if((I|0)!=3)if(m>>>0<=1073741823)if((I|0)==2)k=34;else k=m>>>0>536870911?35:51;else k=18;else k=17;else k=1;else{do switch(I|0){case 8:{k=d[1056+(m>>>26)>>0]|0;break}case 9:{k=d[1120+(m>>>26)>>0]|0;break}case 2:{k=d[736+(m>>>26)>>0]|0;break}case 1:{if(m>>>0>268435455)k=d[672+(m>>>27)>>0]|0;else k=d[704+k>>0]|0;break}case 13:{k=d[1248+(m>>>29)>>0]|0;break}case 14:{k=d[1256+(m>>>30)>>0]|0;break}case 3:{k=d[800+(m>>>26)>>0]|0;break}case 4:{k=d[864+(m>>>27)>>0]|0;break}case 5:{k=d[896+(m>>>27)>>0]|0;break}case 10:{k=d[1184+(m>>>27)>>0]|0;break}case 6:{k=d[928+(m>>>26)>>0]|0;break}case 7:{k=d[992+(m>>>26)>>0]|0;break}case 11:{k=d[1216+(m>>>28)>>0]|0;break}case 12:{k=d[1232+(m>>>28)>>0]|0;break}default:{k=m>>31&16|1;break c}}while(0);if(!k){C=1;i=O;return C|0}}while(0);n=k&15;l=l-n|0;m=m<>>4&15}else n=0;p=I+-1|0;f=(p|0)==0;if(f){c[b+(n<<2)>>2]=c[M+(p<<2)>>2];K=l;h=1<>2]=1;L=l;j=0}else{if(l>>>0<11){if((lb(a,32-l|0)|0)==-1){J=1;k=127;break}l=32;k=kb(a)|0}switch(n|0){case 4:{m=d[648+(k>>>29)>>0]|0;break}case 5:{m=d[656+(k>>>29)>>0]|0;break}case 6:{m=d[664+(k>>>29)>>0]|0;break}case 1:{m=d[624+(k>>>31)>>0]|0;break}case 2:{m=d[632+(k>>>30)>>0]|0;break}case 3:{m=d[640+(k>>>30)>>0]|0;break}default:{do if(k>>>0<=536870911)if(k>>>0<=268435455)if(k>>>0<=134217727)if(k>>>0<=67108863)if(k>>>0<=33554431)if(k>>>0>16777215)m=184;else{if(k>>>0>8388607){m=201;break}if(k>>>0>4194303){m=218;break}m=k>>>0<2097152?0:235}else m=167;else m=150;else m=133;else m=116;else m=k>>>29<<4^115;while(0);if((m>>>4&15)>>>0>n>>>0){J=1;k=127;break d}}}if(!m){J=1;k=127;break}C=m&15;j=m>>>4&15;c[N+(o<<2)>>2]=j+1;L=l-C|0;k=k<>>0>=p>>>0){k=122;break}else{l=L;n=j}}if((k|0)==122){c[b+(j<<2)>>2]=c[M+(p<<2)>>2];h=1<>2]|0)+j|0;h=1<>2]=c[M+(k<<2)>>2];if(!k){K=L;break}else k=k+-1|0}}else if((k|0)==127){i=O;return J|0}}else{K=p;h=0}while(0);if(lb(a,32-K|0)|0){C=1;i=O;return C|0}C=h<<16|I<<4;i=O;return C|0}function sb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;a:do if((jb(a,1)|0)!=-1?(e=b+4|0,c[e>>2]=jb(a,2)|0,d=jb(a,5)|0,c[b>>2]=d,(d+-2|0)>>>0>=3):0){switch(d|0){case 6:case 9:case 10:case 11:case 12:{if(c[e>>2]|0){d=1;break a}break}case 5:case 7:case 8:{if(!(c[e>>2]|0)){d=1;break a}switch(d|0){case 6:case 9:case 10:case 11:case 12:{d=1;break a}default:{}}break}default:{}}d=0}else d=1;while(0);i=f;return d|0}function tb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;if(!d){i=o;return}m=b+-1|0;j=1-b|0;k=~b;g=0;h=0;l=0;while(1){f=(g|0)!=0;if(f)c[a+(h*216|0)+200>>2]=a+((h+-1|0)*216|0);else c[a+(h*216|0)+200>>2]=0;e=(l|0)!=0;if(e){c[a+(h*216|0)+204>>2]=a+((h-b|0)*216|0);if(g>>>0>>0)c[a+(h*216|0)+208>>2]=a+((j+h|0)*216|0);else n=10}else{c[a+(h*216|0)+204>>2]=0;n=10}if((n|0)==10){n=0;c[a+(h*216|0)+208>>2]=0}if(e&f)c[a+(h*216|0)+212>>2]=a+((h+k|0)*216|0);else c[a+(h*216|0)+212>>2]=0;e=g+1|0;f=(e|0)==(b|0);h=h+1|0;if((h|0)==(d|0))break;else{g=f?0:e;l=(f&1)+l|0}}i=o;return}function ub(a,b){a=a|0;b=b|0;var d=0;d=i;switch(b|0){case 1:{a=c[a+204>>2]|0;break}case 3:{a=c[a+212>>2]|0;break}case 4:break;case 2:{a=c[a+208>>2]|0;break}case 0:{a=c[a+200>>2]|0;break}default:a=0}i=d;return a|0}function vb(a){a=a|0;return 3152+(a<<3)|0}function wb(a){a=a|0;return 2960+(a<<3)|0}function xb(a){a=a|0;return 2768+(a<<3)|0}function yb(a){a=a|0;return 2576+(a<<3)|0}function zb(a,b){a=a|0;b=b|0;var d=0;d=i;if(!b){i=d;return 0}else{i=d;return (c[a+4>>2]|0)==(c[b+4>>2]|0)|0}return 0}function Ab(a){a=a|0;var b=0;b=i;id(a,0,3388);c[a+8>>2]=32;c[a+4>>2]=256;c[a+1332>>2]=1;i=b;return}function Bb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;f=c[b+8>>2]|0;g=a+(f<<2)+20|0;e=c[g>>2]|0;do if(!e){d=fd(92)|0;c[g>>2]=d;if(!d){d=65535;i=h;return d|0}}else{d=a+8|0;if((f|0)!=(c[d>>2]|0)){gd(c[e+40>>2]|0);c[(c[g>>2]|0)+40>>2]=0;gd(c[(c[g>>2]|0)+84>>2]|0);c[(c[g>>2]|0)+84>>2]=0;break}f=a+16|0;if(Ra(b,c[f>>2]|0)|0){gd(c[(c[g>>2]|0)+40>>2]|0);c[(c[g>>2]|0)+40>>2]=0;gd(c[(c[g>>2]|0)+84>>2]|0);c[(c[g>>2]|0)+84>>2]=0;c[d>>2]=33;c[a+4>>2]=257;c[f>>2]=0;c[a+12>>2]=0;break}d=b+40|0;gd(c[d>>2]|0);c[d>>2]=0;d=b+84|0;gd(c[d>>2]|0);c[d>>2]=0;d=0;i=h;return d|0}while(0);f=(c[g>>2]|0)+0|0;d=b+0|0;e=f+92|0;do{c[f>>2]=c[d>>2];f=f+4|0;d=d+4|0}while((f|0)<(e|0));d=0;i=h;return d|0}function Cb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;f=c[b>>2]|0;g=a+(f<<2)+148|0;d=c[g>>2]|0;do if(!d){d=fd(72)|0;c[g>>2]=d;if(!d){d=65535;i=h;return d|0}}else{e=a+4|0;if((f|0)!=(c[e>>2]|0)){gd(c[d+20>>2]|0);c[(c[g>>2]|0)+20>>2]=0;gd(c[(c[g>>2]|0)+24>>2]|0);c[(c[g>>2]|0)+24>>2]=0;gd(c[(c[g>>2]|0)+28>>2]|0);c[(c[g>>2]|0)+28>>2]=0;gd(c[(c[g>>2]|0)+44>>2]|0);c[(c[g>>2]|0)+44>>2]=0;break}if((c[b+4>>2]|0)!=(c[a+8>>2]|0)){c[e>>2]=257;d=c[g>>2]|0}gd(c[d+20>>2]|0);c[(c[g>>2]|0)+20>>2]=0;gd(c[(c[g>>2]|0)+24>>2]|0);c[(c[g>>2]|0)+24>>2]=0;gd(c[(c[g>>2]|0)+28>>2]|0);c[(c[g>>2]|0)+28>>2]=0;gd(c[(c[g>>2]|0)+44>>2]|0);c[(c[g>>2]|0)+44>>2]=0}while(0);f=(c[g>>2]|0)+0|0;d=b+0|0;e=f+72|0;do{c[f>>2]=c[d>>2];f=f+4|0;d=d+4|0}while((f|0)<(e|0));d=0;i=h;return d|0}function Db(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;o=a+(b<<2)+148|0;f=c[o>>2]|0;if(!f){o=1;i=q;return o|0}n=c[f+4>>2]|0;g=c[a+(n<<2)+20>>2]|0;if(!g){o=1;i=q;return o|0}l=c[g+52>>2]|0;m=Z(c[g+56>>2]|0,l)|0;h=c[f+12>>2]|0;a:do if(h>>>0>1){g=c[f+16>>2]|0;if((g|0)==2){k=c[f+24>>2]|0;j=c[f+28>>2]|0;h=h+-1|0;e=0;while(1){f=c[k+(e<<2)>>2]|0;g=c[j+(e<<2)>>2]|0;if(!(f>>>0<=g>>>0&g>>>0>>0)){e=1;g=33;break}e=e+1|0;if(((f>>>0)%(l>>>0)|0)>>>0>((g>>>0)%(l>>>0)|0)>>>0){e=1;g=33;break}if(e>>>0>=h>>>0)break a}if((g|0)==33){i=q;return e|0}}else if(!g){g=c[f+20>>2]|0;f=0;while(1){if((c[g+(f<<2)>>2]|0)>>>0>m>>>0){e=1;break}f=f+1|0;if(f>>>0>=h>>>0)break a}i=q;return e|0}else{if((g+-3|0)>>>0<3){if((c[f+36>>2]|0)>>>0>m>>>0)e=1;else break;i=q;return e|0}if((g|0)!=6)break;if((c[f+40>>2]|0)>>>0>>0)e=1;else break;i=q;return e|0}}while(0);f=a+4|0;g=c[f>>2]|0;do if((g|0)!=256){e=a+3380|0;if(!(c[e>>2]|0)){if((g|0)==(b|0))break;g=a+8|0;if((n|0)==(c[g>>2]|0)){c[f>>2]=b;c[a+12>>2]=c[o>>2];break}if(!d){o=1;i=q;return o|0}else{c[f>>2]=b;o=c[o>>2]|0;c[a+12>>2]=o;o=c[o+4>>2]|0;c[g>>2]=o;o=c[a+(o<<2)+20>>2]|0;c[a+16>>2]=o;n=c[o+52>>2]|0;o=c[o+56>>2]|0;c[a+1176>>2]=Z(o,n)|0;c[a+1340>>2]=n;c[a+1344>>2]=o;c[e>>2]=1;break}}c[e>>2]=0;e=a+1212|0;gd(c[e>>2]|0);c[e>>2]=0;f=a+1172|0;gd(c[f>>2]|0);c[f>>2]=0;g=a+1176|0;c[e>>2]=fd((c[g>>2]|0)*216|0)|0;o=fd(c[g>>2]<<2)|0;c[f>>2]=o;f=c[e>>2]|0;if((f|0)==0|(o|0)==0){o=65535;i=q;return o|0}id(f,0,(c[g>>2]|0)*216|0);f=a+16|0;tb(c[e>>2]|0,c[(c[f>>2]|0)+52>>2]|0,c[g>>2]|0);f=c[f>>2]|0;do if((c[a+1216>>2]|0)==0?(c[f+16>>2]|0)!=2:0){if(((c[f+80>>2]|0)!=0?(p=c[f+84>>2]|0,(c[p+920>>2]|0)!=0):0)?(c[p+944>>2]|0)==0:0){e=1;break}e=0}else e=1;while(0);o=Z(c[f+56>>2]|0,c[f+52>>2]|0)|0;e=lc(a+1220|0,o,c[f+88>>2]|0,c[f+44>>2]|0,c[f+12>>2]|0,e)|0;if(e){o=e;i=q;return o|0}}else{c[f>>2]=b;o=c[o>>2]|0;c[a+12>>2]=o;o=c[o+4>>2]|0;c[a+8>>2]=o;o=c[a+(o<<2)+20>>2]|0;c[a+16>>2]=o;n=c[o+52>>2]|0;o=c[o+56>>2]|0;c[a+1176>>2]=Z(o,n)|0;c[a+1340>>2]=n;c[a+1344>>2]=o;c[a+3380>>2]=1}while(0);o=0;i=q;return o|0}function Eb(a){a=a|0;var b=0,d=0,e=0;e=i;c[a+1196>>2]=0;c[a+1192>>2]=0;d=c[a+1176>>2]|0;if(!d){i=e;return}a=c[a+1212>>2]|0;b=0;do{c[a+(b*216|0)+4>>2]=0;c[a+(b*216|0)+196>>2]=0;b=b+1|0}while(b>>>0>>0);i=e;return}function Fb(a){a=a|0;return (c[a+1188>>2]|0)==0|0}function Gb(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;if(!(c[a+1404>>2]|0)){if((c[a+1196>>2]|0)==(c[a+1176>>2]|0)){a=1;i=f;return a|0}}else{e=c[a+1176>>2]|0;if(!e){a=1;i=f;return a|0}a=c[a+1212>>2]|0;b=0;d=0;do{d=((c[a+(b*216|0)+196>>2]|0)!=0&1)+d|0;b=b+1|0}while(b>>>0>>0);if((d|0)==(e|0)){a=1;i=f;return a|0}}a=0;i=f;return a|0}function Hb(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;e=c[a+16>>2]|0;Kb(c[a+1172>>2]|0,c[a+12>>2]|0,b,c[e+52>>2]|0,c[e+56>>2]|0);i=d;return}function Ib(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;i=i+32|0;g=t+24|0;j=t+20|0;k=t+16|0;n=t+12|0;r=t+8|0;q=t;c[e>>2]=0;switch(c[b>>2]|0){case 5:case 1:{s=d+1300|0;h=d+1332|0;if(c[h>>2]|0){c[e>>2]=1;c[h>>2]=0}h=Ua(a,g)|0;if(h){o=h;i=t;return o|0}l=c[d+(c[g>>2]<<2)+148>>2]|0;if(!l){o=65520;i=t;return o|0}h=c[l+4>>2]|0;m=c[d+(h<<2)+20>>2]|0;if(!m){o=65520;i=t;return o|0}g=c[d+8>>2]|0;if(!((g|0)==32|(h|0)==(g|0))?(c[b>>2]|0)!=5:0){o=65520;i=t;return o|0}g=c[d+1304>>2]|0;h=c[b+4>>2]|0;if((g|0)!=(h|0)?(g|0)==0|(h|0)==0:0)c[e>>2]=1;h=(c[b>>2]|0)==5;if((c[s>>2]|0)==5){if(!h)f=16}else if(h)f=16;if((f|0)==16)c[e>>2]=1;g=m+12|0;if(Va(a,c[g>>2]|0,j)|0){o=1;i=t;return o|0}f=d+1308|0;h=c[j>>2]|0;if((c[f>>2]|0)!=(h|0)){c[f>>2]=h;c[e>>2]=1}if((c[b>>2]|0)==5){if(Wa(a,c[g>>2]|0,5,k)|0){o=1;i=t;return o|0}if((c[s>>2]|0)==5){h=d+1312|0;f=c[h>>2]|0;g=c[k>>2]|0;if((f|0)==(g|0))g=f;else c[e>>2]=1}else{g=c[k>>2]|0;h=d+1312|0}c[h>>2]=g}g=c[m+16>>2]|0;if((g|0)==1){if(!(c[m+24>>2]|0)){h=l+8|0;g=Za(a,m,c[b>>2]|0,c[h>>2]|0,q)|0;if(g){o=g;i=t;return o|0}f=d+1324|0;g=c[q>>2]|0;if((c[f>>2]|0)!=(g|0)){c[f>>2]=g;c[e>>2]=1}if((c[h>>2]|0)!=0?(p=d+1328|0,o=c[q+4>>2]|0,(c[p>>2]|0)!=(o|0)):0){c[p>>2]=o;c[e>>2]=1}}}else if(!g){if(Xa(a,m,c[b>>2]|0,n)|0){o=1;i=t;return o|0}f=d+1316|0;g=c[n>>2]|0;if((c[f>>2]|0)!=(g|0)){c[f>>2]=g;c[e>>2]=1}if(c[l+8>>2]|0){f=Ya(a,m,c[b>>2]|0,r)|0;if(f){o=f;i=t;return o|0}g=d+1320|0;f=c[r>>2]|0;if((c[g>>2]|0)!=(f|0)){c[g>>2]=f;c[e>>2]=1}}}n=b;a=c[n+4>>2]|0;o=s;c[o>>2]=c[n>>2];c[o+4>>2]=a;o=0;i=t;return o|0}case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 16:case 17:case 18:{c[e>>2]=1;o=0;i=t;return o|0}default:{o=0;i=t;return o|0}}return 0}function Jb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;n=i;l=0;a:while(1){b=c[a+(l<<2)+148>>2]|0;b:do if((b|0)!=0?(k=c[a+(c[b+4>>2]<<2)+20>>2]|0,(k|0)!=0):0){j=c[k+52>>2]|0;m=Z(c[k+56>>2]|0,j)|0;f=c[b+12>>2]|0;if(f>>>0<=1){b=0;d=18;break a}d=c[b+16>>2]|0;if((d|0)==2){h=c[b+24>>2]|0;g=c[b+28>>2]|0;f=f+-1|0;e=0;while(1){b=c[h+(e<<2)>>2]|0;d=c[g+(e<<2)>>2]|0;if(!(b>>>0<=d>>>0&d>>>0>>0))break b;e=e+1|0;if(((b>>>0)%(j>>>0)|0)>>>0>((d>>>0)%(j>>>0)|0)>>>0)break b;if(e>>>0>=f>>>0){b=0;d=18;break a}}}else if(d){if((d+-3|0)>>>0<3)if((c[b+36>>2]|0)>>>0>m>>>0)break;else{b=0;d=18;break a}if((d|0)!=6){b=0;d=18;break a}if((c[b+40>>2]|0)>>>0>>0)break;else{b=0;d=18;break a}}else{d=c[b+20>>2]|0;b=0;while(1){if((c[d+(b<<2)>>2]|0)>>>0>m>>>0)break b;b=b+1|0;if(b>>>0>=f>>>0){b=0;d=18;break a}}}}while(0);l=l+1|0;if(l>>>0>=256){b=1;d=18;break}}if((d|0)==18){i=n;return b|0}return 0}function Kb(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=i;t=Z(f,e)|0;o=c[b+12>>2]|0;if((o|0)==1){id(a,0,t<<2);i=v;return}k=c[b+16>>2]|0;if((k+-3|0)>>>0<3){d=Z(c[b+36>>2]|0,d)|0;d=d>>>0>>0?d:t;if((k&-2|0)==4){n=(c[b+32>>2]|0)==0?d:t-d|0;u=d}else{n=0;u=d}}else{n=0;u=0}switch(k|0){case 0:{l=c[b+20>>2]|0;if(!t){i=v;return}else{h=0;j=0}while(1){while(1)if(h>>>0>>0)break;else h=0;b=l+(h<<2)|0;d=c[b>>2]|0;a:do if(!d)d=0;else{k=0;do{g=k+j|0;if(g>>>0>=t>>>0)break a;c[a+(g<<2)>>2]=h;k=k+1|0;d=c[b>>2]|0}while(k>>>0>>0)}while(0);j=d+j|0;if(j>>>0>=t>>>0)break;else h=h+1|0}i=v;return}case 4:{h=c[b+32>>2]|0;if(!t){i=v;return}d=1-h|0;g=0;do{c[a+(g<<2)>>2]=g>>>0>>0?h:d;g=g+1|0}while((g|0)!=(t|0));i=v;return}case 1:{if(!t){i=v;return}else h=0;do{c[a+(h<<2)>>2]=((((Z((h>>>0)/(e>>>0)|0,o)|0)>>>1)+((h>>>0)%(e>>>0)|0)|0)>>>0)%(o>>>0)|0;h=h+1|0}while((h|0)!=(t|0));i=v;return}case 2:{n=c[b+24>>2]|0;m=c[b+28>>2]|0;h=o+-1|0;if(t){d=0;do{c[a+(d<<2)>>2]=h;d=d+1|0}while((d|0)!=(t|0))}if(!h){i=v;return}g=o+-2|0;while(1){j=c[n+(g<<2)>>2]|0;d=(j>>>0)/(e>>>0)|0;j=(j>>>0)%(e>>>0)|0;h=c[m+(g<<2)>>2]|0;l=(h>>>0)/(e>>>0)|0;h=(h>>>0)%(e>>>0)|0;b:do if(d>>>0<=l>>>0){if(j>>>0>h>>>0)while(1){d=d+1|0;if(d>>>0>l>>>0)break b}do{k=Z(d,e)|0;b=j;do{c[a+(b+k<<2)>>2]=g;b=b+1|0}while(b>>>0<=h>>>0);d=d+1|0}while(d>>>0<=l>>>0)}while(0);if(!g)break;else g=g+-1|0}i=v;return}case 5:{d=c[b+32>>2]|0;if(!e){i=v;return}k=1-d|0;if(!f){i=v;return}else{g=0;j=0}while(1){h=0;b=j;while(1){m=a+((Z(h,e)|0)+g<<2)|0;c[m>>2]=b>>>0>>0?d:k;h=h+1|0;if((h|0)==(f|0))break;else b=b+1|0}g=g+1|0;if((g|0)==(e|0))break;else j=j+f|0}i=v;return}case 3:{m=c[b+32>>2]|0;if(t){d=0;do{c[a+(d<<2)>>2]=1;d=d+1|0}while((d|0)!=(t|0))}l=(e-m|0)>>>1;n=(f-m|0)>>>1;if(!u){i=v;return}t=m<<1;r=t+-1|0;s=e+-1|0;t=1-t|0;q=f+-1|0;o=n;p=0;g=l;f=l;k=n;b=l;j=m+-1|0;d=n;while(1){n=a+((Z(d,e)|0)+b<<2)|0;l=(c[n>>2]|0)==1;h=l&1;if(l)c[n>>2]=0;do if(!((j|0)==-1&(b|0)==(g|0))){if((j|0)==1&(b|0)==(f|0)){b=f+1|0;b=(b|0)<(s|0)?b:s;n=o;l=g;f=b;j=0;m=t;break}if((m|0)==-1&(d|0)==(k|0)){d=k+-1|0;d=(d|0)>0?d:0;n=o;l=g;k=d;j=t;m=0;break}if((m|0)==1&(d|0)==(o|0)){d=o+1|0;d=(d|0)<(q|0)?d:q;n=d;l=g;j=r;m=0;break}else{n=o;l=g;b=b+j|0;d=d+m|0;break}}else{b=g+-1|0;b=(b|0)>0?b:0;n=o;l=b;j=0;m=r}while(0);p=h+p|0;if(p>>>0>=u>>>0)break;else{o=n;g=l}}i=v;return}default:{if(!t){i=v;return}g=c[b+44>>2]|0;h=0;do{c[a+(h<<2)>>2]=c[g+(h<<2)>>2];h=h+1|0}while((h|0)!=(t|0));i=v;return}}}function Lb(){return 3472}function Mb(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0;k=i;i=i+80|0;h=k+32|0;j=k;Nb(d,h,j,e);if((cb(c[a>>2]|0)|0)==1){e=Ob(a,g,b+328|0,h,j,f)|0;if(e){i=k;return e|0}}else{e=Pb(a,g,b,h,j,f)|0;if(e){i=k;return e|0}}e=Qb(a,g+256|0,b+1352|0,h+21|0,j+16|0,c[b+140>>2]|0,f)|0;if(e){i=k;return e|0}if((c[a+196>>2]|0)>>>0>1){e=0;i=k;return e|0}sc(d,g);e=0;i=k;return e|0}function Nb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=i;if(!f){i=s;return}p=c[b+4>>2]|0;q=Z(c[b+8>>2]|0,p)|0;n=(f>>>0)/(p>>>0)|0;g=Z(n,p)|0;o=f-g|0;k=p<<4;h=c[b>>2]|0;j=(o<<4)+(Z(p<<8,n)|0)|0;r=(n|0)!=0;if(r){m=j-(k|1)|0;a[d>>0]=a[h+m>>0]|0;a[d+1>>0]=a[h+(m+1)>>0]|0;a[d+2>>0]=a[h+(m+2)>>0]|0;a[d+3>>0]=a[h+(m+3)>>0]|0;a[d+4>>0]=a[h+(m+4)>>0]|0;a[d+5>>0]=a[h+(m+5)>>0]|0;a[d+6>>0]=a[h+(m+6)>>0]|0;a[d+7>>0]=a[h+(m+7)>>0]|0;a[d+8>>0]=a[h+(m+8)>>0]|0;a[d+9>>0]=a[h+(m+9)>>0]|0;a[d+10>>0]=a[h+(m+10)>>0]|0;a[d+11>>0]=a[h+(m+11)>>0]|0;a[d+12>>0]=a[h+(m+12)>>0]|0;a[d+13>>0]=a[h+(m+13)>>0]|0;a[d+14>>0]=a[h+(m+14)>>0]|0;a[d+15>>0]=a[h+(m+15)>>0]|0;a[d+16>>0]=a[h+(m+16)>>0]|0;a[d+17>>0]=a[h+(m+17)>>0]|0;a[d+18>>0]=a[h+(m+18)>>0]|0;a[d+19>>0]=a[h+(m+19)>>0]|0;a[d+20>>0]=a[h+(m+20)>>0]|0;m=d+21|0}else m=d;l=(g|0)!=(f|0);if(l){j=j+-1|0;a[e>>0]=a[h+j>>0]|0;j=j+k|0;a[e+1>>0]=a[h+j>>0]|0;j=j+k|0;a[e+2>>0]=a[h+j>>0]|0;j=j+k|0;a[e+3>>0]=a[h+j>>0]|0;j=j+k|0;a[e+4>>0]=a[h+j>>0]|0;j=j+k|0;a[e+5>>0]=a[h+j>>0]|0;j=j+k|0;a[e+6>>0]=a[h+j>>0]|0;j=j+k|0;a[e+7>>0]=a[h+j>>0]|0;j=j+k|0;a[e+8>>0]=a[h+j>>0]|0;j=j+k|0;a[e+9>>0]=a[h+j>>0]|0;j=j+k|0;a[e+10>>0]=a[h+j>>0]|0;j=j+k|0;a[e+11>>0]=a[h+j>>0]|0;j=j+k|0;a[e+12>>0]=a[h+j>>0]|0;j=j+k|0;a[e+13>>0]=a[h+j>>0]|0;j=j+k|0;a[e+14>>0]=a[h+j>>0]|0;a[e+15>>0]=a[h+(j+k)>>0]|0;e=e+16|0}d=p<<3&2147483640;f=c[b>>2]|0;g=(Z(n<<3,d)|0)+(q<<8)+(o<<3)|0;if(r){b=g-(d|1)|0;a[m>>0]=a[f+b>>0]|0;a[m+1>>0]=a[f+(b+1)>>0]|0;a[m+2>>0]=a[f+(b+2)>>0]|0;a[m+3>>0]=a[f+(b+3)>>0]|0;a[m+4>>0]=a[f+(b+4)>>0]|0;a[m+5>>0]=a[f+(b+5)>>0]|0;a[m+6>>0]=a[f+(b+6)>>0]|0;a[m+7>>0]=a[f+(b+7)>>0]|0;a[m+8>>0]=a[f+(b+8)>>0]|0;b=b+(q<<6)|0;a[m+9>>0]=a[f+b>>0]|0;a[m+10>>0]=a[f+(b+1)>>0]|0;a[m+11>>0]=a[f+(b+2)>>0]|0;a[m+12>>0]=a[f+(b+3)>>0]|0;a[m+13>>0]=a[f+(b+4)>>0]|0;a[m+14>>0]=a[f+(b+5)>>0]|0;a[m+15>>0]=a[f+(b+6)>>0]|0;a[m+16>>0]=a[f+(b+7)>>0]|0;a[m+17>>0]=a[f+(b+8)>>0]|0}if(!l){i=s;return}m=g+-1|0;a[e>>0]=a[f+m>>0]|0;m=m+d|0;a[e+1>>0]=a[f+m>>0]|0;m=m+d|0;a[e+2>>0]=a[f+m>>0]|0;m=m+d|0;a[e+3>>0]=a[f+m>>0]|0;m=m+d|0;a[e+4>>0]=a[f+m>>0]|0;m=m+d|0;a[e+5>>0]=a[f+m>>0]|0;m=m+d|0;a[e+6>>0]=a[f+m>>0]|0;m=m+d|0;a[e+7>>0]=a[f+m>>0]|0;m=m+(d+((q<<6)-(p<<6)))|0;a[e+8>>0]=a[f+m>>0]|0;m=m+d|0;a[e+9>>0]=a[f+m>>0]|0;m=m+d|0;a[e+10>>0]=a[f+m>>0]|0;m=m+d|0;a[e+11>>0]=a[f+m>>0]|0;m=m+d|0;a[e+12>>0]=a[f+m>>0]|0;m=m+d|0;a[e+13>>0]=a[f+m>>0]|0;m=m+d|0;a[e+14>>0]=a[f+m>>0]|0;a[e+15>>0]=a[f+(m+d)>>0]|0;i=s;return}function Ob(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;z=i;k=b+200|0;l=zb(b,c[k>>2]|0)|0;o=(j|0)!=0;if((l|0)!=0&o){n=(cb(c[c[k>>2]>>2]|0)|0)==2;n=n?0:l}else n=l;j=b+204|0;l=zb(b,c[j>>2]|0)|0;if((l|0)!=0&o){p=(cb(c[c[j>>2]>>2]|0)|0)==2;p=p?0:l}else p=l;j=b+212|0;l=zb(b,c[j>>2]|0)|0;if((l|0)!=0&o){r=(cb(c[c[j>>2]>>2]|0)|0)==2;l=r?0:l}j=fb(c[b>>2]|0)|0;if(!j){if(!p){r=1;i=z;return r|0}b=g+1|0;m=g+2|0;s=g+3|0;t=g+4|0;u=g+5|0;v=g+6|0;w=g+7|0;x=g+8|0;y=g+9|0;h=g+10|0;l=g+11|0;j=g+12|0;k=g+13|0;q=g+14|0;r=g+15|0;p=g+16|0;o=e;n=0;while(1){a[o>>0]=a[b>>0]|0;a[o+1>>0]=a[m>>0]|0;a[o+2>>0]=a[s>>0]|0;a[o+3>>0]=a[t>>0]|0;a[o+4>>0]=a[u>>0]|0;a[o+5>>0]=a[v>>0]|0;a[o+6>>0]=a[w>>0]|0;a[o+7>>0]=a[x>>0]|0;a[o+8>>0]=a[y>>0]|0;a[o+9>>0]=a[h>>0]|0;a[o+10>>0]=a[l>>0]|0;a[o+11>>0]=a[j>>0]|0;a[o+12>>0]=a[k>>0]|0;a[o+13>>0]=a[q>>0]|0;a[o+14>>0]=a[r>>0]|0;a[o+15>>0]=a[p>>0]|0;n=n+1|0;if((n|0)==16)break;else o=o+16|0}}else if((j|0)==2){l=g+1|0;k=(n|0)!=0;j=(p|0)!=0;do if(!(k&j)){if(k){k=((d[h>>0]|0)+8+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)+(d[h+4>>0]|0)+(d[h+5>>0]|0)+(d[h+6>>0]|0)+(d[h+7>>0]|0)+(d[h+8>>0]|0)+(d[h+9>>0]|0)+(d[h+10>>0]|0)+(d[h+11>>0]|0)+(d[h+12>>0]|0)+(d[h+13>>0]|0)+(d[h+14>>0]|0)+(d[h+15>>0]|0)|0)>>>4;break}if(j)k=((d[l>>0]|0)+8+(d[g+2>>0]|0)+(d[g+3>>0]|0)+(d[g+4>>0]|0)+(d[g+5>>0]|0)+(d[g+6>>0]|0)+(d[g+7>>0]|0)+(d[g+8>>0]|0)+(d[g+9>>0]|0)+(d[g+10>>0]|0)+(d[g+11>>0]|0)+(d[g+12>>0]|0)+(d[g+13>>0]|0)+(d[g+14>>0]|0)+(d[g+15>>0]|0)+(d[g+16>>0]|0)|0)>>>4;else k=128}else{j=0;k=0;do{r=j;j=j+1|0;k=(d[g+j>>0]|0)+k+(d[h+r>>0]|0)|0}while((j|0)!=16);k=(k+16|0)>>>5}while(0);nd(e|0,k&255|0,256)|0}else if((j|0)==1)if(!n){r=1;i=z;return r|0}else{k=e;j=0;while(1){r=h+j|0;a[k>>0]=a[r>>0]|0;a[k+1>>0]=a[r>>0]|0;a[k+2>>0]=a[r>>0]|0;a[k+3>>0]=a[r>>0]|0;a[k+4>>0]=a[r>>0]|0;a[k+5>>0]=a[r>>0]|0;a[k+6>>0]=a[r>>0]|0;a[k+7>>0]=a[r>>0]|0;a[k+8>>0]=a[r>>0]|0;a[k+9>>0]=a[r>>0]|0;a[k+10>>0]=a[r>>0]|0;a[k+11>>0]=a[r>>0]|0;a[k+12>>0]=a[r>>0]|0;a[k+13>>0]=a[r>>0]|0;a[k+14>>0]=a[r>>0]|0;a[k+15>>0]=a[r>>0]|0;j=j+1|0;if((j|0)==16)break;else k=k+16|0}}else{if(!((n|0)!=0&(p|0)!=0&(l|0)!=0)){r=1;i=z;return r|0}j=d[g+16>>0]|0;m=d[h+15>>0]|0;o=d[g>>0]|0;p=(((d[g+9>>0]|0)-(d[g+7>>0]|0)+((d[g+10>>0]|0)-(d[g+6>>0]|0)<<1)+(((d[g+11>>0]|0)-(d[g+5>>0]|0)|0)*3|0)+((d[g+12>>0]|0)-(d[g+4>>0]|0)<<2)+(((d[g+13>>0]|0)-(d[g+3>>0]|0)|0)*5|0)+(((d[g+14>>0]|0)-(d[g+2>>0]|0)|0)*6|0)+(((d[g+15>>0]|0)-(d[g+1>>0]|0)|0)*7|0)+(j-o<<3)|0)*5|0)+32>>6;o=(((d[h+8>>0]|0)-(d[h+6>>0]|0)+(m-o<<3)+((d[h+9>>0]|0)-(d[h+5>>0]|0)<<1)+(((d[h+10>>0]|0)-(d[h+4>>0]|0)|0)*3|0)+((d[h+11>>0]|0)-(d[h+3>>0]|0)<<2)+(((d[h+12>>0]|0)-(d[h+2>>0]|0)|0)*5|0)+(((d[h+13>>0]|0)-(d[h+1>>0]|0)|0)*6|0)+(((d[h+14>>0]|0)-(d[h>>0]|0)|0)*7|0)|0)*5|0)+32>>6;j=(m+j<<4)+16|0;m=0;do{k=j+(Z(m+-7|0,o)|0)|0;n=m<<4;b=0;do{l=k+(Z(b+-7|0,p)|0)>>5;if((l|0)<0)l=0;else l=(l|0)>255?-1:l&255;a[e+(b+n)>>0]=l;b=b+1|0}while((b|0)!=16);m=m+1|0}while((m|0)!=16)}Rb(e,f,0);Rb(e,f+64|0,1);Rb(e,f+128|0,2);Rb(e,f+192|0,3);Rb(e,f+256|0,4);Rb(e,f+320|0,5);Rb(e,f+384|0,6);Rb(e,f+448|0,7);Rb(e,f+512|0,8);Rb(e,f+576|0,9);Rb(e,f+640|0,10);Rb(e,f+704|0,11);Rb(e,f+768|0,12);Rb(e,f+832|0,13);Rb(e,f+896|0,14);Rb(e,f+960|0,15);r=0;i=z;return r|0}function Pb(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0;N=i;M=(j|0)!=0;L=0;a:while(1){l=vb(L)|0;n=c[l+4>>2]|0;l=ub(b,c[l>>2]|0)|0;j=zb(b,l)|0;if((j|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;j=E?0:j}o=wb(L)|0;m=c[o+4>>2]|0;o=ub(b,c[o>>2]|0)|0;k=zb(b,o)|0;if((k|0)!=0&M){E=(cb(c[o>>2]|0)|0)==2;k=E?0:k}G=(j|0)!=0;H=(k|0)!=0;I=G&H;if(I){if(!(cb(c[l>>2]|0)|0))n=d[l+(n&255)+82>>0]|0;else n=2;if(!(cb(c[o>>2]|0)|0))j=d[o+(m&255)+82>>0]|0;else j=2;j=n>>>0>>0?n:j}else j=2;if(!(c[f+(L<<2)+12>>2]|0)){E=c[f+(L<<2)+76>>2]|0;j=(E>>>0>=j>>>0&1)+E|0}a[b+L+82>>0]=j;l=c[(xb(L)|0)>>2]|0;l=ub(b,l)|0;m=zb(b,l)|0;if((m|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;m=E?0:m}l=c[(yb(L)|0)>>2]|0;l=ub(b,l)|0;n=zb(b,l)|0;if((n|0)!=0&M){E=(cb(c[l>>2]|0)|0)==2;n=E?0:n}J=c[3344+(L<<2)>>2]|0;K=c[3408+(L<<2)>>2]|0;r=(1285>>>L&1|0)!=0;if(r){o=h+K|0;l=h+(K+1)|0;p=h+(K+2)|0;q=h+(K+3)|0}else{q=(K<<4)+J|0;o=e+(q+-1)|0;l=e+(q+15)|0;p=e+(q+31)|0;q=e+(q+47)|0}A=a[o>>0]|0;y=a[l>>0]|0;F=a[p>>0]|0;E=a[q>>0]|0;do if(!(51>>>L&1)){x=K+-1|0;w=(x<<4)+J|0;o=a[e+w>>0]|0;q=a[e+(w+1)>>0]|0;s=a[e+(w+2)>>0]|0;u=a[e+(w+3)>>0]|0;t=a[e+(w+4)>>0]|0;l=a[e+(w+5)>>0]|0;v=a[e+(w+6)>>0]|0;p=a[e+(w+7)>>0]|0;if(r){D=v;C=u;u=p;B=q;z=s;v=h+x|0;break}else{D=v;C=u;u=p;B=q;z=s;v=e+(w+-1)|0;break}}else{D=a[g+(J+7)>>0]|0;C=a[g+(J+4)>>0]|0;t=a[g+(J+5)>>0]|0;l=a[g+(J+6)>>0]|0;o=a[g+(J+1)>>0]|0;u=a[g+(J+8)>>0]|0;B=a[g+(J+2)>>0]|0;z=a[g+(J+3)>>0]|0;v=g+J|0}while(0);v=a[v>>0]|0;switch(j|0){case 4:{if(!(I&(n|0)!=0)){k=1;j=51;break a}j=o&255;o=v&255;q=A&255;s=j+2|0;D=(s+q+(o<<1)|0)>>>2;u=D&255;k=B&255;o=o+2|0;v=((j<<1)+k+o|0)>>>2&255;j=z&255;s=((k<<1)+j+s|0)>>>2&255;z=y&255;o=(z+(q<<1)+o|0)>>>2;t=o&255;A=F&255;B=(q+2+(z<<1)+A|0)>>>2;q=u;p=t;n=B&255;m=v;l=s;j=((C&255)+2+k+(j<<1)|0)>>>2&255;k=u;r=v;o=(z+2+(A<<1)+(E&255)|0)>>>2&255|B<<8&65280|D<<24|o<<16&16711680;break}case 6:{if(!(I&(n|0)!=0)){k=1;j=51;break a}l=v&255;s=A&255;u=s+1|0;r=(u+l|0)>>>1&255;C=y&255;v=((s<<1)+2+C+l|0)>>>2&255;u=(u+C|0)>>>1&255;D=F&255;s=s+2|0;y=(s+(C<<1)+D|0)>>>2;A=(C+1+D|0)>>>1;E=E&255;j=o&255;s=(s+j+(l<<1)|0)>>>2&255;k=B&255;q=r;p=u;n=A&255;m=s;l=(k+2+(j<<1)+l|0)>>>2&255;j=((z&255)+2+(k<<1)+j|0)>>>2&255;k=v;t=y&255;o=y<<24|A<<16&16711680|(D+1+E|0)>>>1&255|C+2+(D<<1)+E<<6&65280;break}case 2:{do if(!I){if(G){j=((A&255)+2+(y&255)+(F&255)+(E&255)|0)>>>2;break}if(H)j=((C&255)+2+(z&255)+(B&255)+(o&255)|0)>>>2;else j=128}else j=((A&255)+4+(y&255)+(F&255)+(E&255)+(C&255)+(z&255)+(B&255)+(o&255)|0)>>>3;while(0);o=Z(j&255,16843009)|0;n=o&255;t=o>>>8&255;u=o>>>16&255;v=o>>>24&255;q=n;p=n;m=t;l=u;j=v;k=t;r=u;s=v;break}case 0:{if(!k){k=1;j=51;break a}q=o;p=o;n=o;m=B;l=z;j=C;k=B;r=z;s=C;t=B;u=z;v=C;o=(z&255)<<16|(C&255)<<24|(B&255)<<8|o&255;break}case 1:{if(!G){k=1;j=51;break a}j=Z(A&255,16843009)|0;s=Z(y&255,16843009)|0;v=Z(F&255,16843009)|0;q=j&255;p=s&255;n=v&255;m=j>>>8&255;l=j>>>16&255;j=j>>>24&255;k=s>>>8&255;r=s>>>16&255;s=s>>>24&255;t=v>>>8&255;u=v>>>16&255;v=v>>>24&255;o=Z(E&255,16843009)|0;break}case 7:{if(!k){k=1;j=51;break a}A=(m|0)==0;n=o&255;p=B&255;z=z&255;m=(z+1+p|0)>>>1&255;o=C&255;u=o+1|0;v=(u+z|0)>>>1&255;B=(A?C:t)&255;u=(u+B|0)>>>1&255;j=z+2|0;y=o+2|0;z=(y+p+(z<<1)|0)>>>2;o=(j+(o<<1)+B|0)>>>2;E=(A?C:l)&255;y=(y+E+(B<<1)|0)>>>2;q=(p+1+n|0)>>>1&255;p=(j+n+(p<<1)|0)>>>2&255;n=m;l=v;j=u;k=z&255;r=o&255;s=y&255;t=v;v=(B+1+E|0)>>>1&255;o=y<<16&16711680|z&255|(B+2+((A?C:D)&255)+(E<<1)|0)>>>2<<24|o<<8&65280;break}case 3:{if(!k){k=1;j=51;break a}n=(m|0)==0;q=B&255;m=z&255;p=m+2|0;k=C&255;B=k+2|0;m=(B+q+(m<<1)|0)>>>2&255;v=(n?C:t)&255;k=(p+(k<<1)+v|0)>>>2&255;E=(n?C:l)&255;B=(B+E+(v<<1)|0)>>>2;t=B&255;A=(n?C:D)&255;D=(v+2+A+(E<<1)|0)>>>2;v=D&255;C=(n?C:u)&255;E=(E+2+C+(A<<1)|0)>>>2;q=(p+(o&255)+(q<<1)|0)>>>2&255;p=m;n=k;l=k;j=t;r=t;s=v;u=v;v=E&255;o=(A+2+(C*3|0)|0)>>>2<<24|B&255|D<<8&65280|E<<16&16711680;break}case 5:{if(!(I&(n|0)!=0)){k=1;j=51;break a}n=v&255;u=o&255;t=(u+1+n|0)>>>1&255;x=B&255;E=(x+2+(u<<1)+n|0)>>>2;B=A&255;A=u+2|0;o=(A+B+(n<<1)|0)>>>2;u=(x+1+u|0)>>>1&255;s=z&255;A=((x<<1)+s+A|0)>>>2;v=(s+1+x|0)>>>1&255;C=C&255;D=y&255;q=t;p=o&255;n=(D+2+(B<<1)+n|0)>>>2&255;m=u;l=v;j=(C+1+s|0)>>>1&255;k=E&255;r=A&255;s=(C+2+x+(s<<1)|0)>>>2&255;o=A<<24|(B+2+(F&255)+(D<<1)|0)>>>2&255|E<<16&16711680|o<<8&65280;break}default:{if(!G){k=1;j=51;break a}s=A&255;j=y&255;m=F&255;l=(j+1+m|0)>>>1&255;o=E&255;k=(j+2+(m<<1)+o|0)>>>2&255;r=(m+1+o|0)>>>1&255;t=(m+2+(o*3|0)|0)>>>2&255;q=(s+1+j|0)>>>1&255;p=l;n=r;m=(s+2+(j<<1)+m|0)>>>2&255;j=k;s=t;u=E;v=E;o=o<<8|o|o<<16|o<<24}}E=(K<<4)+J|0;c[e+E>>2]=(l&255)<<16|(j&255)<<24|(m&255)<<8|q&255;c[e+(E+16)>>2]=(r&255)<<16|(s&255)<<24|(k&255)<<8|p&255;c[e+(E+32)>>2]=(u&255)<<16|(v&255)<<24|(t&255)<<8|n&255;c[e+(E+48)>>2]=o;Rb(e,f+(L<<6)+328|0,L);L=L+1|0;if(L>>>0>=16){k=0;j=51;break}}if((j|0)==51){i=N;return k|0}return 0}function Qb(b,e,f,g,h,j,k){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;y=i;m=b+200|0;l=zb(b,c[m>>2]|0)|0;n=(k|0)!=0;if((l|0)!=0&n){o=(cb(c[c[m>>2]>>2]|0)|0)==2;l=o?0:l}m=b+204|0;k=zb(b,c[m>>2]|0)|0;if((k|0)!=0&n){o=(cb(c[c[m>>2]>>2]|0)|0)==2;o=o?0:k}else o=k;m=b+212|0;k=zb(b,c[m>>2]|0)|0;if((k|0)!=0&n){n=(cb(c[c[m>>2]>>2]|0)|0)==2;k=n?0:k}w=(l|0)!=0;x=(o|0)!=0;v=w&x;u=v&(k|0)!=0;t=(l|0)==0;s=(o|0)==0;p=g;q=16;r=0;while(1){if((j|0)==1){if(t){l=1;k=29;break}else{n=e;b=8;m=h}while(1){b=b+-1|0;a[n>>0]=a[m>>0]|0;a[n+1>>0]=a[m>>0]|0;a[n+2>>0]=a[m>>0]|0;a[n+3>>0]=a[m>>0]|0;a[n+4>>0]=a[m>>0]|0;a[n+5>>0]=a[m>>0]|0;a[n+6>>0]=a[m>>0]|0;a[n+7>>0]=a[m>>0]|0;if(!b)break;else{n=n+8|0;m=m+1|0}}}else if((j|0)==2){if(s){l=1;k=29;break}else{n=p;b=e;m=8}while(1){n=n+1|0;m=m+-1|0;a[b>>0]=a[n>>0]|0;a[b+8>>0]=a[n>>0]|0;a[b+16>>0]=a[n>>0]|0;a[b+24>>0]=a[n>>0]|0;a[b+32>>0]=a[n>>0]|0;a[b+40>>0]=a[n>>0]|0;a[b+48>>0]=a[n>>0]|0;a[b+56>>0]=a[n>>0]|0;if(!m)break;else b=b+1|0}}else if(!j){m=p+1|0;do if(!v){if(x){n=((d[m>>0]|0)+2+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)|0)>>>2;b=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2;break}if(w){b=((d[h>>0]|0)+2+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)|0)>>>2;n=b}else{n=128;b=128}}else{n=((d[m>>0]|0)+4+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)+(d[h>>0]|0)+(d[h+1>>0]|0)+(d[h+2>>0]|0)+(d[h+3>>0]|0)|0)>>>3;b=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2}while(0);n=n&255;o=b&255;nd(e|0,n|0,4)|0;nd(e+4|0,o|0,4)|0;nd(e+8|0,n|0,4)|0;nd(e+12|0,o|0,4)|0;nd(e+16|0,n|0,4)|0;nd(e+20|0,o|0,4)|0;g=e+32|0;nd(e+24|0,n|0,4)|0;nd(e+28|0,o|0,4)|0;if(w){o=d[h+4>>0]|0;n=d[h+5>>0]|0;b=d[h+6>>0]|0;m=d[h+7>>0]|0;k=(o+2+n+b+m|0)>>>2;if(x){l=k;n=(o+4+n+b+m+(d[p+5>>0]|0)+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>3}else{l=k;n=k}}else if(x){l=((d[m>>0]|0)+2+(d[p+2>>0]|0)+(d[p+3>>0]|0)+(d[p+4>>0]|0)|0)>>>2;n=((d[p+5>>0]|0)+2+(d[p+6>>0]|0)+(d[p+7>>0]|0)+(d[p+8>>0]|0)|0)>>>2}else{l=128;n=128}b=l&255;o=n&255;nd(g|0,b|0,4)|0;nd(e+36|0,o|0,4)|0;nd(e+40|0,b|0,4)|0;nd(e+44|0,o|0,4)|0;nd(e+48|0,b|0,4)|0;nd(e+52|0,o|0,4)|0;nd(e+56|0,b|0,4)|0;nd(e+60|0,o|0,4)|0}else{if(!u){l=1;k=29;break}n=d[p+8>>0]|0;b=d[h+7>>0]|0;l=d[p>>0]|0;k=(((d[p+5>>0]|0)-(d[p+3>>0]|0)+((d[p+6>>0]|0)-(d[p+2>>0]|0)<<1)+(((d[p+7>>0]|0)-(d[p+1>>0]|0)|0)*3|0)+(n-l<<2)|0)*17|0)+16>>5;l=(((d[h+4>>0]|0)-(d[h+2>>0]|0)+(b-l<<2)+((d[h+5>>0]|0)-(d[h+1>>0]|0)<<1)+(((d[h+6>>0]|0)-(d[h>>0]|0)|0)*3|0)|0)*17|0)+16>>5;o=Z(k,-3)|0;n=(b+n<<4)+16+(Z(l,-3)|0)|0;b=e;m=8;while(1){m=m+-1|0;g=n+o|0;a[b>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+1>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+2>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+3>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+4>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+5>>0]=a[(g>>5)+3984>>0]|0;g=g+k|0;a[b+6>>0]=a[(g>>5)+3984>>0]|0;a[b+7>>0]=a[(g+k>>5)+3984>>0]|0;if(!m)break;else{n=n+l|0;b=b+8|0}}}Rb(e,f,q);g=q|1;Rb(e,f+64|0,g);Rb(e,f+128|0,g+1|0);Rb(e,f+192|0,q|3);r=r+1|0;if(r>>>0>=2){l=0;k=29;break}else{p=p+9|0;q=q+4|0;e=e+64|0;h=h+8|0;f=f+256|0}}if((k|0)==29){i=y;return l|0}return 0}function Rb(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;h=i;g=c[e>>2]|0;if((g|0)==16777215){i=h;return}m=f>>>0<16;l=m?16:8;m=m?f:f&3;m=(Z(c[3408+(m<<2)>>2]|0,l)|0)+(c[3344+(m<<2)>>2]|0)|0;n=b+m|0;p=c[e+4>>2]|0;j=b+(m+1)|0;f=d[j>>0]|0;a[n>>0]=a[3472+(g+512+(d[n>>0]|0))>>0]|0;n=c[e+8>>2]|0;k=b+(m+2)|0;o=d[k>>0]|0;a[j>>0]=a[3472+(p+512+f)>>0]|0;g=b+(m+3)|0;j=a[3472+((c[e+12>>2]|0)+512+(d[g>>0]|0))>>0]|0;a[k>>0]=a[3472+(n+512+o)>>0]|0;a[g>>0]=j;g=m+l|0;m=b+g|0;j=c[e+20>>2]|0;k=b+(g+1)|0;o=d[k>>0]|0;a[m>>0]=a[3472+((c[e+16>>2]|0)+512+(d[m>>0]|0))>>0]|0;m=c[e+24>>2]|0;n=b+(g+2)|0;f=d[n>>0]|0;a[k>>0]=a[3472+(j+512+o)>>0]|0;k=b+(g+3)|0;o=a[3472+((c[e+28>>2]|0)+512+(d[k>>0]|0))>>0]|0;a[n>>0]=a[3472+(m+512+f)>>0]|0;a[k>>0]=o;g=g+l|0;k=b+g|0;o=c[e+36>>2]|0;n=b+(g+1)|0;f=d[n>>0]|0;a[k>>0]=a[3472+((c[e+32>>2]|0)+512+(d[k>>0]|0))>>0]|0;k=c[e+40>>2]|0;m=b+(g+2)|0;j=d[m>>0]|0;a[n>>0]=a[3472+(o+512+f)>>0]|0;n=b+(g+3)|0;f=a[3472+((c[e+44>>2]|0)+512+(d[n>>0]|0))>>0]|0;a[m>>0]=a[3472+(k+512+j)>>0]|0;a[n>>0]=f;g=g+l|0;l=b+g|0;n=c[e+52>>2]|0;f=b+(g+1)|0;m=d[f>>0]|0;a[l>>0]=a[3472+((c[e+48>>2]|0)+512+(d[l>>0]|0))>>0]|0;l=c[e+56>>2]|0;j=b+(g+2)|0;k=d[j>>0]|0;a[f>>0]=a[3472+(n+512+m)>>0]|0;g=b+(g+3)|0;f=a[3472+((c[e+60>>2]|0)+512+(d[g>>0]|0))>>0]|0;a[j>>0]=a[3472+(l+512+k)>>0]|0;a[g>>0]=f;i=h;return} +function yc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;q=i;l=b+-1|0;k=a[b+1>>0]|0;m=d[l>>0]|0;n=d[b>>0]|0;r=m-n|0;p=f+4|0;do if((((r|0)>-1?r:0-r|0)>>>0<(c[p>>2]|0)>>>0?(o=d[b+-2>>0]|0,r=o-m|0,j=c[f+8>>2]|0,((r|0)>-1?r:0-r|0)>>>0>>0):0)?(h=k&255,k=h-n|0,((k|0)>-1?k:0-k|0)>>>0>>0):0)if(e>>>0<4){k=d[(c[f>>2]|0)+(e+-1)>>0]|0;k=Oa(~k,k+1|0,4-h+(n-m<<2)+o>>3)|0;o=a[3472+((n|512)-k)>>0]|0;a[l>>0]=a[3472+((m|512)+k)>>0]|0;a[b>>0]=o;break}else{a[l>>0]=(m+2+h+(o<<1)|0)>>>2;a[b>>0]=(n+2+(h<<1)+o|0)>>>2;break}while(0);l=b+g|0;m=b+(g+-1)|0;o=d[m>>0]|0;n=d[l>>0]|0;k=o-n|0;if(((k|0)>-1?k:0-k|0)>>>0>=(c[p>>2]|0)>>>0){i=q;return}k=d[b+(g+-2)>>0]|0;p=k-o|0;j=c[f+8>>2]|0;if(((p|0)>-1?p:0-p|0)>>>0>=j>>>0){i=q;return}h=d[b+(g+1)>>0]|0;g=h-n|0;if(((g|0)>-1?g:0-g|0)>>>0>=j>>>0){i=q;return}if(e>>>0<4){b=d[(c[f>>2]|0)+(e+-1)>>0]|0;b=Oa(~b,b+1|0,4-h+(n-o<<2)+k>>3)|0;g=a[3472+((n|512)-b)>>0]|0;a[m>>0]=a[3472+((o|512)+b)>>0]|0;a[l>>0]=g;i=q;return}else{a[m>>0]=(o+2+h+(k<<1)|0)>>>2;a[l>>0]=(n+2+(h<<1)+k|0)>>>2;i=q;return}}function zc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=i;if(e>>>0<4){n=d[(c[f>>2]|0)+(e+-1)>>0]|0;h=n+1|0;q=0-g|0;e=f+4|0;p=q<<1;o=f+8|0;n=~n;j=8;while(1){m=b+q|0;f=a[b+g>>0]|0;l=d[m>>0]|0;k=d[b>>0]|0;r=l-k|0;if((((r|0)>-1?r:0-r|0)>>>0<(c[e>>2]|0)>>>0?(t=d[b+p>>0]|0,r=t-l|0,s=c[o>>2]|0,((r|0)>-1?r:0-r|0)>>>0>>0):0)?(u=f&255,f=u-k|0,((f|0)>-1?f:0-f|0)>>>0>>0):0){r=Oa(n,h,4-u+(k-l<<2)+t>>3)|0;f=a[3472+((k|512)-r)>>0]|0;a[m>>0]=a[3472+((l|512)+r)>>0]|0;a[b>>0]=f}j=j+-1|0;if(!j)break;else b=b+1|0}i=v;return}else{o=0-g|0;m=f+4|0;n=o<<1;f=f+8|0;l=8;while(1){h=b+o|0;e=a[b+g>>0]|0;j=d[h>>0]|0;k=d[b>>0]|0;s=j-k|0;if((((s|0)>-1?s:0-s|0)>>>0<(c[m>>2]|0)>>>0?(p=d[b+n>>0]|0,s=p-j|0,q=c[f>>2]|0,((s|0)>-1?s:0-s|0)>>>0>>0):0)?(r=e&255,e=r-k|0,((e|0)>-1?e:0-e|0)>>>0>>0):0){a[h>>0]=(j+2+r+(p<<1)|0)>>>2;a[b>>0]=(k+2+(r<<1)+p|0)>>>2}l=l+-1|0;if(!l)break;else b=b+1|0}i=v;return}}function Ac(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;t=i;r=d[(c[f>>2]|0)+(e+-1)>>0]|0;s=r+1|0;l=0-g|0;h=f+4|0;q=l<<1;e=f+8|0;r=~r;l=b+l|0;m=a[b+g>>0]|0;k=d[l>>0]|0;j=d[b>>0]|0;u=k-j|0;f=c[h>>2]|0;if((((u|0)>-1?u:0-u|0)>>>0>>0?(o=d[b+q>>0]|0,u=o-k|0,n=c[e>>2]|0,((u|0)>-1?u:0-u|0)>>>0>>0):0)?(p=m&255,m=p-j|0,((m|0)>-1?m:0-m|0)>>>0>>0):0){p=Oa(r,s,4-p+(j-k<<2)+o>>3)|0;f=a[3472+((j|512)-p)>>0]|0;a[l>>0]=a[3472+((k|512)+p)>>0]|0;a[b>>0]=f;f=c[h>>2]|0}m=b+1|0;j=b+(1-g)|0;k=d[j>>0]|0;l=d[m>>0]|0;p=k-l|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}h=d[b+(q|1)>>0]|0;p=h-k|0;f=c[e>>2]|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}e=d[b+(g+1)>>0]|0;p=e-l|0;if(((p|0)>-1?p:0-p|0)>>>0>=f>>>0){i=t;return}o=Oa(r,s,4-e+(l-k<<2)+h>>3)|0;p=a[3472+((l|512)-o)>>0]|0;a[j>>0]=a[3472+((k|512)+o)>>0]|0;a[m>>0]=p;i=t;return}function Bc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;p=c[b+4>>2]|0;q=c[b+8>>2]|0;if(!((d|0)==0|(d|0)==5)?(c[a+3384>>2]|0)==0:0)f=0;else{g=a+1220|0;e=0;do{f=ic(g,e)|0;e=e+1|0}while(e>>>0<16&(f|0)==0)}l=a+1176|0;n=c[l>>2]|0;if(n){m=c[a+1212>>2]|0;e=0;j=0;g=0;do{if(c[m+(j*216|0)+196>>2]|0)break;j=j+1|0;e=e+1|0;o=(e|0)==(p|0);g=(o&1)+g|0;e=o?0:e}while(j>>>0>>0);if((j|0)!=(n|0)){o=a+1212|0;n=c[o>>2]|0;j=Z(g,p)|0;if(e){l=a+1204|0;h=e;do{h=h+-1|0;m=h+j|0;Cc(n+(m*216|0)|0,b,g,h,d,f);c[n+(m*216|0)+196>>2]=1;c[l>>2]=(c[l>>2]|0)+1}while((h|0)!=0)}e=e+1|0;if(e>>>0

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%0ANtX zT29RBhY_E~oK9$-6XFXCJ5L+sFT%IfmG13v3aLZ5V4eR@mva*CE&v4|D5Y-d`2${beuA_UpE)M&HVG zx_ZTb@k7I!1>7-9qNbK*T|C7Yhs>H8%gM1+4d=;Eo2bSC{b^V$g{T!s*!*!&J+MR%&*5zO>pKv zji`4+gs literal 0 HcmV?d00001 diff --git a/tools/matchFeaturesTest/matchFeaturesTest.js b/tools/matchFeaturesTest/matchFeaturesTest.js new file mode 100644 index 0000000..ba2cf48 --- /dev/null +++ b/tools/matchFeaturesTest/matchFeaturesTest.js @@ -0,0 +1,98 @@ +const cv = require('opencv4nodejs'); + +width = 800 + +textIn = 0 +textOut = 0 + +testIntersectionIn = function(x, y): + + res = -450 * x + 400 * y + 157500 + if((res >= -550) and (res < 550)): + print (str(res)) + return True + return False + + + +testIntersectionOut = function(x, y): + res = -450 * x + 400 * y + 180000 + if ((res >= -550) and (res <= 550)): + print (str(res)) + return True + + return False + +camera = cv2.VideoCapture("test2.mp4") + +firstFrame = None + +# loop over the frames of the video +while True: + # grab the current frame and initialize the occupied/unoccupied + # text + (grabbed, frame) = camera.read() + text = "Unoccupied" + + # if the frame could not be grabbed, then we have reached the end + # of the video + if not grabbed: + break + + # resize the frame, convert it to grayscale, and blur it + frame = imutils.resize(frame, width=width) + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + gray = cv2.GaussianBlur(gray, (21, 21), 0) + + # if the first frame is None, initialize it + if firstFrame is None: + firstFrame = gray + continue + + # compute the absolute difference between the current frame and + # first frame + frameDelta = cv2.absdiff(firstFrame, gray) + thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1] + # dilate the thresholded image to fill in holes, then find contours + # on thresholded image + thresh = cv2.dilate(thresh, None, iterations=2) + _, cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + # loop over the contours + for c in cnts: + # if the contour is too small, ignore it + if cv2.contourArea(c) < 12000: + continue + # compute the bounding box for the contour, draw it on the frame, + # and update the text + (x, y, w, h) = cv2.boundingRect(c) + cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) + + cv2.line(frame, (width / 2, 0), (width, 450), (250, 0, 1), 2) #blue line + cv2.line(frame, (width / 2 - 50, 0), (width - 50, 450), (0, 0, 255), 2)#red line + + + rectagleCenterPont = ((x + x + w) /2, (y + y + h) /2) + cv2.circle(frame, rectagleCenterPont, 1, (0, 0, 255), 5) + + if(testIntersectionIn((x + x + w) / 2, (y + y + h) / 2)): + textIn += 1 + + if(testIntersectionOut((x + x + w) / 2, (y + y + h) / 2)): + textOut += 1 + + # draw the text and timestamp on the frame + + # show the frame and record if the user presses a key + # cv2.imshow("Thresh", thresh) + # cv2.imshow("Frame Delta", frameDelta) + + if cv2.waitKey(1) & 0xFF == ord('q'): + break + + cv2.putText(frame, "In: {}".format(str(textIn)), (10, 50), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) + cv2.putText(frame, "Out: {}".format(str(textOut)), (10, 70), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) + cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"), + (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1) + cv2.imshow("Security Feed", frame) \ No newline at end of file diff --git a/tools/matchFeaturesTest/waldo.jpg b/tools/matchFeaturesTest/waldo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d5e01d745a80b3fd01c9cd2ad49b185930e1f5f8 GIT binary patch literal 1280 zcmex=kR1VV=P zOa>M(n}I8aRU`>6#zP&nVE@&nUxh}4Pz}(o`FS>RY=j$kxe)-kzJ`! z#HexNLJno8jR!@8E`CrkPAY2R|V^&07y2J$~}^+4C1KUw!=a`ODXD-+%o41@ad# zJR#l!k`SMv`3o2bj7%&n%q;96e=#zZgFG(C!m4P(ZXWYowZ;xuvL#)F*7 z#z7xMlZq~KiK&=8RQ(9@8rWyVd8~;npTRwb@YihyX9hMF78X_(Hda0Ukbn0e(InVPO#wVPP3*X=xdGIQS1Vgpr+{otKAKLO?)5N>or( z3NA@3 z-3m~f&?&Cf`Sd|cfal4xE?={*EtiP8bGdr=@6{)jZ|#%FC_evi@rsH`$t$yOwH}#n z)xCr3!U?AZ4GTkVB)bG|(O}*#`l<4mQPys6Z*6(YD7$ap?EhbA_xv#T?y`kzqn6Dr z%r7qz`a8)jqVtb%6$=<>>iN*G_l!MJ@E8X!}7Oec|j7I>Y%>%9vhLtVKVP1jHuGdd|{AkHzYx(~d z+x}(PxZ6an{;}IHQ!!%B%~xXl+-}J_#{{L;+-}U|P6Kkd(Uos0{an{KFHz208`P-WU1?&j4u zJ6wt?yEua-O9V~QH8;9lU{GFL^G|87yZL)JxuB?D>y-~qdG}twa^IT&mp`6O{^w+F m|Mi^xU*6R*h4-8O$@E=6y#LjE`_~WZU(8s2DBalp|4jg$+2MTv literal 0 HcmV?d00001 diff --git a/tools/modifyConfiguration.js b/tools/modifyConfiguration.js new file mode 100644 index 0000000..f73fbea --- /dev/null +++ b/tools/modifyConfiguration.js @@ -0,0 +1,30 @@ +process.on('uncaughtException', function (err) { + console.error('Uncaught Exception occured!'); + console.error(err.stack); +}); +var configLocation = __dirname+'/../conf.json'; +var fs = require('fs'); +var jsonfile = require("jsonfile"); +var config = jsonfile.readFileSync(configLocation); +var processArgv = process.argv.splice(2,process.argv.length) +var arguments = {}; +processArgv.forEach(function(val) { + var theSplit = val.split('='); + var index = theSplit[0]; + var value = theSplit[1]; + if(value==='DELETE'){ + delete(config[index]) + }else{ + try{ + config[index] = JSON.parse(value); + }catch(err){ + config[index] = value; + } + } + console.log(index + ': ' + value); +}); + +jsonfile.writeFile(configLocation,config,{spaces: 2},function(){ + console.log('Changes Complete. Here is what it is now.') + console.log(JSON.stringify(config,null,2)) +}) \ No newline at end of file diff --git a/tools/sql2mongo/mesh.js b/tools/sql2mongo/mesh.js new file mode 100644 index 0000000..660a463 --- /dev/null +++ b/tools/sql2mongo/mesh.js @@ -0,0 +1,2342 @@ +/*global print, _, moment, db, ObjectId, hostname */ +/*! + * mesh - the MongoDB Extended Shell + * + * Version: 1.5.0 + * Date: September 25th, 2013 + * Project: http://skratchdot.com/projects/mesh/ + * Source Code: https://github.com/skratchdot/mesh/ + * Issues: https://github.com/skratchdot/mesh/issues/ + * Included Libraries: https://github.com/skratchdot/mesh/#whats-included + * Dependencies: MongoDB v1.8+ + * + * Copyright 2013 + * Dual licensed under the MIT or GPL Version 2 licenses. + * https://raw.github.com/skratchdot/mesh/master/LICENSE-MIT.txt + * https://raw.github.com/skratchdot/mesh/master/LICENSE-GPL.txt + * + */ +var mesh = (function (global) { + 'use strict'; + + var api, + version = "1.5.0", + lastTime = null, + config = { + defaultPrompt : 0, // 0-4 or a string + aliases : {} // can pass in a map of aliases. see: mesh.setAliases(); + }; + + /* + * This is the "mesh" function. If someone types: mesh(), then we will just + * print the current version info. + */ + api = function () { + return api.version(); + }; + + /* + * We can override the default settings by calling this function. + * + * The idea is to keep a "mesh.config.js" file that calls this function. + * + * When updating mesh.js, we will never override mesh.config.js + */ + api.config = function (settings) { + // Handle defaultPrompt + if (settings.hasOwnProperty('defaultPrompt')) { + config.defaultPrompt = settings.defaultPrompt; + api.prompt(config.defaultPrompt); + } + if (settings.hasOwnProperty('aliases') && typeof settings.aliases === 'object') { + api.setAliases(settings.aliases); + } + }; + + /* + * Print the current version + */ + api.version = function () { + return print('mesh (the MongoDB Extended Shell) version: ' + version); + }; + + /* + * Print help information. + * + * TODO: make sure that "help mesh" works as well by overriding default mongo help() + */ + api.help = function () { + api.version(); + print('help coming soon!'); + }; + + /* + * Accept a map of aliases. The keys are the aliases, and the values + * are the paths to the variable. + * + * For instance, if we want to create an aliase for mesh.keys() to be k(), then + * we can call: + * + * mesh.setAliases({'k':'mesh.keys'}); + * + * We can create an alias for printjson() by doing something like: + * + * mesh.setAliases({'pj':'printjson'}); + * + */ + api.setAliases = function (aliases) { + var alias, keys, i, skip, obj; + + // do nothing if we weren't passed key/value pairs + if (typeof aliases !== 'object') { + return; + } + + // loop through our aliases + for (alias in aliases) { + if (aliases.hasOwnProperty(alias)) { + // we process dot delimited strings + keys = aliases[alias]; + if (typeof keys === 'string' && keys.length > 0) { + // we will drill down into the dot delimited string. + // if the given variable path doesn't exist, let's + // try to process the next alias + skip = false; + obj = global; + keys = keys.split('.'); + for (i = 0; i < keys.length; i++) { + if (obj && obj[keys[i]]) { + obj = obj[keys[i]]; + } else { + i = keys.length; + skip = true; + } + } + if (!skip) { + global[alias] = obj; + } + } + } + } + }; + + /* + * Sets the default prompt. + * + * See: http://www.kchodorow.com/blog/2011/06/27/ps1/ + * + * newPrompt can be a function, or a number: + * + * 0: '>' reset to default prompt + * 1: 'dbname>' + * 2: 'dbname>' for PRIMARY, '(dbname)>' for SECONDARY + * 3: 'host:dbname>' + * 4: '[YYYY-MM-DD hh:mm:ss] host:dbname>' + */ + api.prompt = function (newPrompt) { + var base = '> '; + if (typeof newPrompt === 'function') { + global.prompt = newPrompt; + } else if (newPrompt === 1) { + global.prompt = function () { + return db.getName() + base; + }; + } else if (newPrompt === 2) { + global.prompt = function () { + var isMaster = db.isMaster().ismaster; + return (isMaster ? '' : '(') + + db.getName() + + (isMaster ? '' : ')') + + base; + }; + } else if (newPrompt === 3) { + global.prompt = function () { + var isMaster = db.isMaster().ismaster; + return (isMaster ? '' : '(') + + hostname() + ":" + + db.getName() + + (isMaster ? '' : ')') + + base; + }; + } else if (newPrompt === 4) { + global.prompt = function () { + var isMaster = db.isMaster().ismaster; + return '[' + moment().format('YYYY-MM-DD hh:mm:ss') + '] ' + + (isMaster ? '' : '(') + + db.serverStatus().host + ":" + + db.getName() + + (isMaster ? '' : ')') + + base; + }; + } else if (typeof newPrompt === 'string') { + global.prompt = function () { + return newPrompt; + }; + } else { + delete global.prompt; + } + }; + + /* + * A simple wrapper for ObjectId(); + */ + api.oid = function (oidString) { + if (typeof oidString === 'string') { + return new ObjectId(oidString); + } + return new ObjectId(); + }; + + /* + * Generate an ObjectId() based on a time stamp. + * + * usage: + * + * // pass in nothing to get an ObjectId based on the current timestamp + * mesh.tid(); + * // you can pass in any valid Date object + * mesh.tid(new Date()); + * // you can pass in any valid moment object + * mesh.tid(moment()); + * mesh.tid('2 minutes ago'); + * mesh.tid('June 1, 2012'); // returns ObjectId("4fc83e400000000000000000") + * // you can pass in an optional increment value + * mesh.tid('June 1, 2012', 3); // returns ObjectId("4fc83e400000000000000003") + * + * see: + * + * http://www.kchodorow.com/blog/2011/12/20/querying-for-timestamps-using-objectids/ + * http://www.mongodb.org/display/DOCS/Object+IDs + * + * ObjectIds are 12-byte BSON objects: + * + * TimeStamp [bytes 0-3]: + * This is a unix style timestamp. It is a signed int representing + * the number of seconds before or after January 1st 1970 (UTC). + * + * Machine [bytes 4-6] + * This is the first three bytes of the (md5) hash of the machine host + * name, or of the mac/network address, or the virtual machine id. + * + * Pid [bytes 7-8] + * This is 2 bytes of the process id (or thread id) of the process + * generating the ObjectId. + * + * Increment [bytes 9-11] + * This is an ever incrementing value starting with a random number. + */ + api.tid = function (newMoment, inc) { + var theDate, seconds, hexSecs, hexInc; + + // build timestamp portion of ObjectId + newMoment = moment(newMoment); + if (newMoment && newMoment.isValid && newMoment.isValid()) { + theDate = newMoment.toDate(); + } else { + theDate = new Date(); + } + seconds = parseInt(theDate.getTime() / 1000, 10); + hexSecs = seconds.toString(16); + + // build increment portion of ObjectId + if (typeof inc !== 'number') { + inc = 0; + } + hexInc = _.lpad(parseInt(inc, 10).toString(16), 3, '0').substring(0, 3); + return new ObjectId(hexSecs + '0000000000000' + hexInc); + }; + + /* + * Returns a sorted array of all the keys in an object + */ + api.keys = function (obj) { + return _.keys(obj || global).sort(); + }; + + /* + * If passed a function, it will display the function execution time. + * + * If passed anything else, it will just print the current time. + * + * This function keeps track of the last time it was called, and will output + * how long it's been since the last time it was called. + */ + api.time = function (obj) { + var start = moment(), + formatString = 'YYYY-MM-DD hh:mm:ss a'; + + // Current Time + print('Current Time: ' + start.format(formatString)); + + // Last time called + if (lastTime !== null) { + print('Last time called ' + lastTime.fromNow() + ' [' + start.format(formatString) + ']'); + } + + // Execute function if one is passed + if (typeof obj === 'function') { + print('Executing function...'); + obj.apply(); + print(' Started ' + start.fromNow()); + print('Finished: ' + moment().format(formatString)); + } + + // Save last time + lastTime = start; + }; + + return api; +}(this)); + +/*jslint maxerr: 50, indent: 4, plusplus: true */ +/** + * console.js - a quick wrapper so console calls don't error out in the mongodb shell + * + * All console calls are currently just wrappers for the built in print() function that + * comes with the mongo shell. Eventually, it would be good to add "real" behavior to + * the console calls. For instance, console.error() should wrap ThrowError(), and console.timer() + * should work as well. + * + */ +(function (global) { + 'use strict'; + + var i = 0, + functionNames = [ + 'assert', 'clear', 'count', 'debug', 'dir', + 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', + 'groupEnd', 'info', 'log', 'profile', 'profileEnd', 'table', + 'time', 'timeEnd', 'timeStamp', 'trace', 'warn' + ], + wrapperFunction = function () { + print.apply(global, arguments); + }; + + // Make sure console exists + global.console = global.console || {}; + + // Make sure all functions exist + for (i = 0; i < functionNames.length; i++) { + global.console[functionNames[i]] = global.console[functionNames[i]] || wrapperFunction; + } + +}(this)); + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function () { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function () { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); + +/*jslint evil: true, regexp: true */ + +/*members $ref, apply, call, decycle, hasOwnProperty, length, prototype, push, + retrocycle, stringify, test, toString +*/ + +if (typeof JSON.decycle !== 'function') { + JSON.decycle = function decycle(object) { + 'use strict'; + +// Make a deep copy of an object or array, assuring that there is at most +// one instance of each object or array in the resulting structure. The +// duplicate references (which might be forming cycles) are replaced with +// an object of the form +// {$ref: PATH} +// where the PATH is a JSONPath string that locates the first occurance. +// So, +// var a = []; +// a[0] = a; +// return JSON.stringify(JSON.decycle(a)); +// produces the string '[{"$ref":"$"}]'. + +// JSONPath is used to locate the unique object. $ indicates the top level of +// the object or array. [NUMBER] or [STRING] indicates a child member or +// property. + + var objects = [], // Keep a reference to each unique object or array + paths = []; // Keep the path to each unique object or array + + return (function derez(value, path) { + +// The derez recurses through the object, producing the deep copy. + + var i, // The loop counter + name, // Property name + nu; // The new object or array + +// typeof null === 'object', so go on if this value is really an object but not +// one of the weird builtin objects. + + if (typeof value === 'object' && value !== null && + !(value instanceof Boolean) && + !(value instanceof Date) && + !(value instanceof Number) && + !(value instanceof RegExp) && + !(value instanceof String)) { + +// If the value is an object or array, look to see if we have already +// encountered it. If so, return a $ref/path object. This is a hard way, +// linear search that will get slower as the number of unique objects grows. + + for (i = 0; i < objects.length; i += 1) { + if (objects[i] === value) { + return {$ref: paths[i]}; + } + } + +// Otherwise, accumulate the unique value and its path. + + objects.push(value); + paths.push(path); + +// If it is an array, replicate the array. + + if (Object.prototype.toString.apply(value) === '[object Array]') { + nu = []; + for (i = 0; i < value.length; i += 1) { + nu[i] = derez(value[i], path + '[' + i + ']'); + } + } else { + +// If it is an object, replicate the object. + + nu = {}; + for (name in value) { + if (Object.prototype.hasOwnProperty.call(value, name)) { + nu[name] = derez(value[name], + path + '[' + JSON.stringify(name) + ']'); + } + } + } + return nu; + } + return value; + }(object, '$')); + }; +} + + +if (typeof JSON.retrocycle !== 'function') { + JSON.retrocycle = function retrocycle($) { + 'use strict'; + +// Restore an object that was reduced by decycle. Members whose values are +// objects of the form +// {$ref: PATH} +// are replaced with references to the value found by the PATH. This will +// restore cycles. The object will be mutated. + +// The eval function is used to locate the values described by a PATH. The +// root object is kept in a $ variable. A regular expression is used to +// assure that the PATH is extremely well formed. The regexp contains nested +// * quantifiers. That has been known to have extremely bad performance +// problems on some browsers for very long strings. A PATH is expected to be +// reasonably short. A PATH is allowed to belong to a very restricted subset of +// Goessner's JSONPath. + +// So, +// var s = '[{"$ref":"$"}]'; +// return JSON.retrocycle(JSON.parse(s)); +// produces an array containing a single element which is the array itself. + + var px = + /^\$(?:\[(?:\d+|\"(?:[^\\\"\u0000-\u001f]|\\([\\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*\")\])*$/; + + (function rez(value) { + +// The rez function walks recursively through the object looking for $ref +// properties. When it finds one that has a value that is a path, then it +// replaces the $ref object with a reference to the value that is found by +// the path. + + var i, item, name, path; + + if (value && typeof value === 'object') { + if (Object.prototype.toString.apply(value) === '[object Array]') { + for (i = 0; i < value.length; i += 1) { + item = value[i]; + if (item && typeof item === 'object') { + path = item.$ref; + if (typeof path === 'string' && px.test(path)) { + value[i] = eval(path); + } else { + rez(item); + } + } + } + } else { + for (name in value) { + if (typeof value[name] === 'object') { + item = value[name]; + if (item) { + path = item.$ref; + if (typeof path === 'string' && px.test(path)) { + value[name] = eval(path); + } else { + rez(item); + } + } + } + } + } + } + }($)); + return $; + }; +} + +// Underscore.js 1.5.2 +// http://underscorejs.org +// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. +(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,g=e.filter,d=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,w=Object.keys,_=i.bind,j=function(n){return n instanceof j?n:this instanceof j?(this._wrapped=n,void 0):new j(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=j),exports._=j):n._=j,j.VERSION="1.5.2";var A=j.each=j.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a=j.keys(n),u=0,i=a.length;i>u;u++)if(t.call(e,n[a[u]],a[u],n)===r)return};j.map=j.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e.push(t.call(r,n,u,i))}),e)};var E="Reduce of empty array with no initial value";j.reduce=j.foldl=j.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=j.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(E);return r},j.reduceRight=j.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=j.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=j.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(E);return r},j.find=j.detect=function(n,t,r){var e;return O(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},j.filter=j.select=function(n,t,r){var e=[];return null==n?e:g&&n.filter===g?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&e.push(n)}),e)},j.reject=function(n,t,r){return j.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},j.every=j.all=function(n,t,e){t||(t=j.identity);var u=!0;return null==n?u:d&&n.every===d?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var O=j.some=j.any=function(n,t,e){t||(t=j.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};j.contains=j.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:O(n,function(n){return n===t})},j.invoke=function(n,t){var r=o.call(arguments,2),e=j.isFunction(t);return j.map(n,function(n){return(e?t:n[t]).apply(n,r)})},j.pluck=function(n,t){return j.map(n,function(n){return n[t]})},j.where=function(n,t,r){return j.isEmpty(t)?r?void 0:[]:j[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},j.findWhere=function(n,t){return j.where(n,t,!0)},j.max=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.max.apply(Math,n);if(!t&&j.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>e.computed&&(e={value:n,computed:a})}),e.value},j.min=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.min.apply(Math,n);if(!t&&j.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;ae||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={},i=null==r?j.identity:k(r);return A(t,function(r,a){var o=i.call(e,r,a,t);n(u,o,r)}),u}};j.groupBy=F(function(n,t,r){(j.has(n,t)?n[t]:n[t]=[]).push(r)}),j.indexBy=F(function(n,t,r){n[t]=r}),j.countBy=F(function(n,t){j.has(n,t)?n[t]++:n[t]=1}),j.sortedIndex=function(n,t,r,e){r=null==r?j.identity:k(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;r.call(e,n[o])=0})})},j.difference=function(n){var t=c.apply(e,o.call(arguments,1));return j.filter(n,function(n){return!j.contains(t,n)})},j.zip=function(){for(var n=j.max(j.pluck(arguments,"length").concat(0)),t=new Array(n),r=0;n>r;r++)t[r]=j.pluck(arguments,""+r);return t},j.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},j.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=j.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},j.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},j.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=new Array(e);e>u;)i[u++]=n,n+=r;return i};var R=function(){};j.bind=function(n,t){var r,e;if(_&&n.bind===_)return _.apply(n,o.call(arguments,1));if(!j.isFunction(n))throw new TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(o.call(arguments)));R.prototype=n.prototype;var u=new R;R.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return Object(i)===i?i:u}},j.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},j.bindAll=function(n){var t=o.call(arguments,1);if(0===t.length)throw new Error("bindAll must be passed function names");return A(t,function(t){n[t]=j.bind(n[t],n)}),n},j.memoize=function(n,t){var r={};return t||(t=j.identity),function(){var e=t.apply(this,arguments);return j.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},j.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},j.defer=function(n){return j.delay.apply(j,[n,1].concat(o.call(arguments,1)))},j.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var c=function(){o=r.leading===!1?0:new Date,a=null,i=n.apply(e,u)};return function(){var l=new Date;o||r.leading!==!1||(o=l);var f=t-(l-o);return e=this,u=arguments,0>=f?(clearTimeout(a),a=null,o=l,i=n.apply(e,u)):a||r.trailing===!1||(a=setTimeout(c,f)),i}},j.debounce=function(n,t,r){var e,u,i,a,o;return function(){i=this,u=arguments,a=new Date;var c=function(){var l=new Date-a;t>l?e=setTimeout(c,t-l):(e=null,r||(o=n.apply(i,u)))},l=r&&!e;return e||(e=setTimeout(c,t)),l&&(o=n.apply(i,u)),o}},j.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},j.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},j.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},j.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},j.keys=w||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)j.has(n,r)&&t.push(r);return t},j.values=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},j.pairs=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},j.invert=function(n){for(var t={},r=j.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},j.functions=j.methods=function(n){var t=[];for(var r in n)j.isFunction(n[r])&&t.push(r);return t.sort()},j.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},j.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},j.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)j.contains(r,u)||(t[u]=n[u]);return t},j.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]===void 0&&(n[r]=t[r])}),n},j.clone=function(n){return j.isObject(n)?j.isArray(n)?n.slice():j.extend({},n):n},j.tap=function(n,t){return t(n),n};var S=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof j&&(n=n._wrapped),t instanceof j&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==String(t);case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;var a=n.constructor,o=t.constructor;if(a!==o&&!(j.isFunction(a)&&a instanceof a&&j.isFunction(o)&&o instanceof o))return!1;r.push(n),e.push(t);var c=0,f=!0;if("[object Array]"==u){if(c=n.length,f=c==t.length)for(;c--&&(f=S(n[c],t[c],r,e)););}else{for(var s in n)if(j.has(n,s)&&(c++,!(f=j.has(t,s)&&S(n[s],t[s],r,e))))break;if(f){for(s in t)if(j.has(t,s)&&!c--)break;f=!c}}return r.pop(),e.pop(),f};j.isEqual=function(n,t){return S(n,t,[],[])},j.isEmpty=function(n){if(null==n)return!0;if(j.isArray(n)||j.isString(n))return 0===n.length;for(var t in n)if(j.has(n,t))return!1;return!0},j.isElement=function(n){return!(!n||1!==n.nodeType)},j.isArray=x||function(n){return"[object Array]"==l.call(n)},j.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){j["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),j.isArguments(arguments)||(j.isArguments=function(n){return!(!n||!j.has(n,"callee"))}),"function"!=typeof/./&&(j.isFunction=function(n){return"function"==typeof n}),j.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},j.isNaN=function(n){return j.isNumber(n)&&n!=+n},j.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},j.isNull=function(n){return null===n},j.isUndefined=function(n){return n===void 0},j.has=function(n,t){return f.call(n,t)},j.noConflict=function(){return n._=t,this},j.identity=function(n){return n},j.times=function(n,t,r){for(var e=Array(Math.max(0,n)),u=0;n>u;u++)e[u]=t.call(r,u);return e},j.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var I={escape:{"&":"&","<":"<",">":">",'"':""","'":"'"}};I.unescape=j.invert(I.escape);var T={escape:new RegExp("["+j.keys(I.escape).join("")+"]","g"),unescape:new RegExp("("+j.keys(I.unescape).join("|")+")","g")};j.each(["escape","unescape"],function(n){j[n]=function(t){return null==t?"":(""+t).replace(T[n],function(t){return I[n][t]})}}),j.result=function(n,t){if(null==n)return void 0;var r=n[t];return j.isFunction(r)?r.call(n):r},j.mixin=function(n){A(j.functions(n),function(t){var r=j[t]=n[t];j.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),z.call(this,r.apply(j,n))}})};var N=0;j.uniqueId=function(n){var t=++N+"";return n?n+t:t},j.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;j.template=function(n,t,r){var e;r=j.defaults({},r,j.templateSettings);var u=new RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(D,function(n){return"\\"+B[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=new Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,j);var c=function(n){return e.call(this,n,j)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},j.chain=function(n){return j(n).chain()};var z=function(n){return this._chain?j(n).chain():n};j.mixin(j),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];j.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];j.prototype[n]=function(){return z.call(this,t.apply(this._wrapped,arguments))}}),j.extend(j.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this); +//# sourceMappingURL=underscore-min.map +!function(e,n){"use strict";function r(e,n){var r,t,u=e.toLowerCase();for(n=[].concat(n),r=0;n.length>r;r+=1)if(t=n[r]){if(t.test&&t.test(e))return!0;if(t.toLowerCase()===u)return!0}}var t=n.prototype.trim,u=n.prototype.trimRight,i=n.prototype.trimLeft,l=function(e){return 1*e||0},o=function(e,n){if(1>n)return"";for(var r="";n>0;)1&n&&(r+=e),n>>=1,e+=e;return r},a=[].slice,c=function(e){return null==e?"\\s":e.source?e.source:"["+g.escapeRegExp(e)+"]"},s={lt:"<",gt:">",quot:'"',amp:"&",apos:"'"},f={};for(var p in s)f[s[p]]=p;f["'"]="#39";var h=function(){function e(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}var r=o,t=function(){return t.cache.hasOwnProperty(arguments[0])||(t.cache[arguments[0]]=t.parse(arguments[0])),t.format.call(null,t.cache[arguments[0]],arguments)};return t.format=function(t,u){var i,l,o,a,c,s,f,p=1,g=t.length,d="",m=[];for(l=0;g>l;l++)if(d=e(t[l]),"string"===d)m.push(t[l]);else if("array"===d){if(a=t[l],a[2])for(i=u[p],o=0;a[2].length>o;o++){if(!i.hasOwnProperty(a[2][o]))throw new Error(h('[_.sprintf] property "%s" does not exist',a[2][o]));i=i[a[2][o]]}else i=a[1]?u[a[1]]:u[p++];if(/[^s]/.test(a[8])&&"number"!=e(i))throw new Error(h("[_.sprintf] expecting number but found %s",e(i)));switch(a[8]){case"b":i=i.toString(2);break;case"c":i=n.fromCharCode(i);break;case"d":i=parseInt(i,10);break;case"e":i=a[7]?i.toExponential(a[7]):i.toExponential();break;case"f":i=a[7]?parseFloat(i).toFixed(a[7]):parseFloat(i);break;case"o":i=i.toString(8);break;case"s":i=(i=n(i))&&a[7]?i.substring(0,a[7]):i;break;case"u":i=Math.abs(i);break;case"x":i=i.toString(16);break;case"X":i=i.toString(16).toUpperCase()}i=/[def]/.test(a[8])&&a[3]&&i>=0?"+"+i:i,s=a[4]?"0"==a[4]?"0":a[4].charAt(1):" ",f=a[6]-n(i).length,c=a[6]?r(s,f):"",m.push(a[5]?i+c:c+i)}return m.join("")},t.cache={},t.parse=function(e){for(var n=e,r=[],t=[],u=0;n;){if(null!==(r=/^[^\x25]+/.exec(n)))t.push(r[0]);else if(null!==(r=/^\x25{2}/.exec(n)))t.push("%");else{if(null===(r=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(n)))throw new Error("[_.sprintf] huh?");if(r[2]){u|=1;var i=[],l=r[2],o=[];if(null===(o=/^([a-z_][a-z_\d]*)/i.exec(l)))throw new Error("[_.sprintf] huh?");for(i.push(o[1]);""!==(l=l.substring(o[0].length));)if(null!==(o=/^\.([a-z_][a-z_\d]*)/i.exec(l)))i.push(o[1]);else{if(null===(o=/^\[(\d+)\]/.exec(l)))throw new Error("[_.sprintf] huh?");i.push(o[1])}r[2]=i}else u|=2;if(3===u)throw new Error("[_.sprintf] mixing positional and named placeholders is not (yet) supported");t.push(r)}n=n.substring(r[0].length)}return t},t}(),g={VERSION:"2.3.0",isBlank:function(e){return null==e&&(e=""),/^\s*$/.test(e)},stripTags:function(e){return null==e?"":n(e).replace(/<\/?[^>]+>/g,"")},capitalize:function(e){return e=null==e?"":n(e),e.charAt(0).toUpperCase()+e.slice(1)},chop:function(e,r){return null==e?[]:(e=n(e),r=~~r,r>0?e.match(new RegExp(".{1,"+r+"}","g")):[e])},clean:function(e){return g.strip(e).replace(/\s+/g," ")},count:function(e,r){if(null==e||null==r)return 0;e=n(e),r=n(r);for(var t=0,u=0,i=r.length;;){if(u=e.indexOf(r,u),-1===u)break;t++,u+=i}return t},chars:function(e){return null==e?[]:n(e).split("")},swapCase:function(e){return null==e?"":n(e).replace(/\S/g,function(e){return e===e.toUpperCase()?e.toLowerCase():e.toUpperCase()})},escapeHTML:function(e){return null==e?"":n(e).replace(/[&<>"']/g,function(e){return"&"+f[e]+";"})},unescapeHTML:function(e){return null==e?"":n(e).replace(/\&([^;]+);/g,function(e,r){var t;return r in s?s[r]:(t=r.match(/^#x([\da-fA-F]+)$/))?n.fromCharCode(parseInt(t[1],16)):(t=r.match(/^#(\d+)$/))?n.fromCharCode(~~t[1]):e})},escapeRegExp:function(e){return null==e?"":n(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},splice:function(e,n,r,t){var u=g.chars(e);return u.splice(~~n,~~r,t),u.join("")},insert:function(e,n,r){return g.splice(e,n,0,r)},include:function(e,r){return""===r?!0:null==e?!1:-1!==n(e).indexOf(r)},join:function(){var e=a.call(arguments),n=e.shift();return null==n&&(n=""),e.join(n)},lines:function(e){return null==e?[]:n(e).split("\n")},reverse:function(e){return g.chars(e).reverse().join("")},startsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(0,r.length)===r)},endsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(e.length-r.length)===r)},succ:function(e){return null==e?"":(e=n(e),e.slice(0,-1)+n.fromCharCode(e.charCodeAt(e.length-1)+1))},titleize:function(e){return null==e?"":(e=n(e).toLowerCase(),e.replace(/(?:^|\s|-)\S/g,function(e){return e.toUpperCase()}))},camelize:function(e){return g.trim(e).replace(/[-_\s]+(.)?/g,function(e,n){return n?n.toUpperCase():""})},underscored:function(e){return g.trim(e).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()},dasherize:function(e){return g.trim(e).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()},classify:function(e){return g.titleize(n(e).replace(/[\W_]/g," ")).replace(/\s/g,"")},humanize:function(e){return g.capitalize(g.underscored(e).replace(/_id$/,"").replace(/_/g," "))},trim:function(e,r){return null==e?"":!r&&t?t.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+|"+r+"+$","g"),""))},ltrim:function(e,r){return null==e?"":!r&&i?i.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+"),""))},rtrim:function(e,r){return null==e?"":!r&&u?u.call(e):(r=c(r),n(e).replace(new RegExp(r+"+$"),""))},truncate:function(e,r,t){return null==e?"":(e=n(e),t=t||"...",r=~~r,e.length>r?e.slice(0,r)+t:e)},prune:function(e,r,t){if(null==e)return"";if(e=n(e),r=~~r,t=null!=t?n(t):"...",r>=e.length)return e;var u=function(e){return e.toUpperCase()!==e.toLowerCase()?"A":" "},i=e.slice(0,r+1).replace(/.(?=\W*\w*$)/g,u);return i=i.slice(i.length-2).match(/\w\w/)?i.replace(/\s*\S+$/,""):g.rtrim(i.slice(0,i.length-1)),(i+t).length>e.length?e:e.slice(0,i.length)+t},words:function(e,n){return g.isBlank(e)?[]:g.trim(e,n).split(n||/\s+/)},pad:function(e,r,t,u){e=null==e?"":n(e),r=~~r;var i=0;switch(t?t.length>1&&(t=t.charAt(0)):t=" ",u){case"right":return i=r-e.length,e+o(t,i);case"both":return i=r-e.length,o(t,Math.ceil(i/2))+e+o(t,Math.floor(i/2));default:return i=r-e.length,o(t,i)+e}},lpad:function(e,n,r){return g.pad(e,n,r)},rpad:function(e,n,r){return g.pad(e,n,r,"right")},lrpad:function(e,n,r){return g.pad(e,n,r,"both")},sprintf:h,vsprintf:function(e,n){return n.unshift(e),h.apply(null,n)},toNumber:function(e,n){return e?(e=g.trim(e),e.match(/^-?\d+(?:\.\d+)?$/)?l(l(e).toFixed(~~n)):0/0):0},numberFormat:function(e,n,r,t){if(isNaN(e)||null==e)return"";e=e.toFixed(~~n),t="string"==typeof t?t:",";var u=e.split("."),i=u[0],l=u[1]?(r||".")+u[1]:"";return i.replace(/(\d)(?=(?:\d{3})+$)/g,"$1"+t)+l},strRight:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strRightBack:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.lastIndexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strLeft:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(0,t):e},strLeftBack:function(e,n){if(null==e)return"";e+="",n=null!=n?""+n:n;var r=e.lastIndexOf(n);return~r?e.slice(0,r):e},toSentence:function(e,n,r,t){n=n||", ",r=r||" and ";var u=e.slice(),i=u.pop();return e.length>2&&t&&(r=g.rtrim(n)+r),u.length?u.join(n)+r+i:i},toSentenceSerial:function(){var e=a.call(arguments);return e[3]=!0,g.toSentence.apply(g,e)},slugify:function(e){if(null==e)return"";var r="ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź",t="aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz",u=new RegExp(c(r),"g");return e=n(e).toLowerCase().replace(u,function(e){var n=r.indexOf(e);return t.charAt(n)||"-"}),g.dasherize(e.replace(/[^\w\s-]/g,""))},surround:function(e,n){return[n,e,n].join("")},quote:function(e,n){return g.surround(e,n||'"')},unquote:function(e,n){return n=n||'"',e[0]===n&&e[e.length-1]===n?e.slice(1,e.length-1):e},exports:function(){var e={};for(var n in this)this.hasOwnProperty(n)&&!n.match(/^(?:include|contains|reverse)$/)&&(e[n]=this[n]);return e},repeat:function(e,r,t){if(null==e)return"";if(r=~~r,null==t)return o(n(e),r);for(var u=[];r>0;u[--r]=e);return u.join(t)},naturalCmp:function(e,r){if(e==r)return 0;if(!e)return-1;if(!r)return 1;for(var t=/(\.\d+)|(\d+)|(\D+)/g,u=n(e).toLowerCase().match(t),i=n(r).toLowerCase().match(t),l=Math.min(u.length,i.length),o=0;l>o;o++){var a=u[o],c=i[o];if(a!==c){var s=parseInt(a,10);if(!isNaN(s)){var f=parseInt(c,10);if(!isNaN(f)&&s-f)return s-f}return c>a?-1:1}}return u.length===i.length?u.length-i.length:r>e?-1:1},levenshtein:function(e,r){if(null==e&&null==r)return 0;if(null==e)return n(r).length;if(null==r)return n(e).length;e=n(e),r=n(r);for(var t,u,i=[],l=0;r.length>=l;l++)for(var o=0;e.length>=o;o++)u=l&&o?e.charAt(o-1)===r.charAt(l-1)?t:Math.min(i[o],i[o-1],t)+1:l+o,t=i[o],i[o]=u;return i.pop()},toBoolean:function(e,n,t){return"number"==typeof e&&(e=""+e),"string"!=typeof e?!!e:(e=g.trim(e),r(e,n||["true","1"])?!0:r(e,t||["false","0"])?!1:void 0)}};g.strip=g.trim,g.lstrip=g.ltrim,g.rstrip=g.rtrim,g.center=g.lrpad,g.rjust=g.lpad,g.ljust=g.rpad,g.contains=g.include,g.q=g.quote,g.toBool=g.toBoolean,"undefined"!=typeof exports&&("undefined"!=typeof module&&module.exports&&(module.exports=g),exports._s=g),"function"==typeof define&&define.amd&&define("underscore.string",[],function(){return g}),e._=e._||{},e._.string=e._.str=g}(this,String); +//! moment.js +//! version : 2.2.1 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com +(function(a){function b(a,b){return function(c){return i(a.call(this,c),b)}}function c(a,b){return function(c){return this.lang().ordinal(a.call(this,c),b)}}function d(){}function e(a){g(this,a)}function f(a){var b=a.years||a.year||a.y||0,c=a.months||a.month||a.M||0,d=a.weeks||a.week||a.w||0,e=a.days||a.day||a.d||0,f=a.hours||a.hour||a.h||0,g=a.minutes||a.minute||a.m||0,h=a.seconds||a.second||a.s||0,i=a.milliseconds||a.millisecond||a.ms||0;this._input=a,this._milliseconds=+i+1e3*h+6e4*g+36e5*f,this._days=+e+7*d,this._months=+c+12*b,this._data={},this._bubble()}function g(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}function h(a){return 0>a?Math.ceil(a):Math.floor(a)}function i(a,b){for(var c=a+"";c.lengthc;c++)~~a[c]!==~~b[c]&&f++;return f+e}function m(a){return a?ib[a]||a.toLowerCase().replace(/(.)s$/,"$1"):a}function n(a,b){return b.abbr=a,P[a]||(P[a]=new d),P[a].set(b),P[a]}function o(a){delete P[a]}function p(a){if(!a)return L.fn._lang;if(!P[a]&&Q)try{require("./lang/"+a)}catch(b){return L.fn._lang}return P[a]||L.fn._lang}function q(a){return a.match(/\[.*\]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function r(a){var b,c,d=a.match(T);for(b=0,c=d.length;c>b;b++)d[b]=mb[d[b]]?mb[d[b]]:q(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function s(a,b){return b=t(b,a.lang()),jb[b]||(jb[b]=r(b)),jb[b](a)}function t(a,b){function c(a){return b.longDateFormat(a)||a}for(var d=5;d--&&(U.lastIndex=0,U.test(a));)a=a.replace(U,c);return a}function u(a,b){switch(a){case"DDDD":return X;case"YYYY":return Y;case"YYYYY":return Z;case"S":case"SS":case"SSS":case"DDD":return W;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return $;case"a":case"A":return p(b._l)._meridiemParse;case"X":return bb;case"Z":case"ZZ":return _;case"T":return ab;case"MM":case"DD":case"YY":case"HH":case"hh":case"mm":case"ss":case"M":case"D":case"d":case"H":case"h":case"m":case"s":return V;default:return new RegExp(a.replace("\\",""))}}function v(a){var b=(_.exec(a)||[])[0],c=(b+"").match(fb)||["-",0,0],d=+(60*c[1])+~~c[2];return"+"===c[0]?-d:d}function w(a,b,c){var d,e=c._a;switch(a){case"M":case"MM":null!=b&&(e[1]=~~b-1);break;case"MMM":case"MMMM":d=p(c._l).monthsParse(b),null!=d?e[1]=d:c._isValid=!1;break;case"D":case"DD":null!=b&&(e[2]=~~b);break;case"DDD":case"DDDD":null!=b&&(e[1]=0,e[2]=~~b);break;case"YY":e[0]=~~b+(~~b>68?1900:2e3);break;case"YYYY":case"YYYYY":e[0]=~~b;break;case"a":case"A":c._isPm=p(c._l).isPM(b);break;case"H":case"HH":case"h":case"hh":e[3]=~~b;break;case"m":case"mm":e[4]=~~b;break;case"s":case"ss":e[5]=~~b;break;case"S":case"SS":case"SSS":e[6]=~~(1e3*("0."+b));break;case"X":c._d=new Date(1e3*parseFloat(b));break;case"Z":case"ZZ":c._useUTC=!0,c._tzm=v(b)}null==b&&(c._isValid=!1)}function x(a){var b,c,d,e=[];if(!a._d){for(d=z(a),b=0;3>b&&null==a._a[b];++b)a._a[b]=e[b]=d[b];for(;7>b;b++)a._a[b]=e[b]=null==a._a[b]?2===b?1:0:a._a[b];e[3]+=~~((a._tzm||0)/60),e[4]+=~~((a._tzm||0)%60),c=new Date(0),a._useUTC?(c.setUTCFullYear(e[0],e[1],e[2]),c.setUTCHours(e[3],e[4],e[5],e[6])):(c.setFullYear(e[0],e[1],e[2]),c.setHours(e[3],e[4],e[5],e[6])),a._d=c}}function y(a){var b=a._i;a._d||(a._a=[b.years||b.year||b.y,b.months||b.month||b.M,b.days||b.day||b.d,b.hours||b.hour||b.h,b.minutes||b.minute||b.m,b.seconds||b.second||b.s,b.milliseconds||b.millisecond||b.ms],x(a))}function z(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function A(a){var b,c,d,e=p(a._l),f=""+a._i;for(d=t(a._f,e).match(T),a._a=[],b=0;bh&&(i=h,d=c);g(a,d)}function C(a){var b,c=a._i,d=cb.exec(c);if(d){for(a._f="YYYY-MM-DD"+(d[2]||" "),b=0;4>b;b++)if(eb[b][1].exec(c)){a._f+=eb[b][0];break}_.exec(c)&&(a._f+=" Z"),A(a)}else a._d=new Date(c)}function D(b){var c=b._i,d=R.exec(c);c===a?b._d=new Date:d?b._d=new Date(+d[1]):"string"==typeof c?C(b):k(c)?(b._a=c.slice(0),x(b)):c instanceof Date?b._d=new Date(+c):"object"==typeof c?y(b):b._d=new Date(c)}function E(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function F(a,b,c){var d=O(Math.abs(a)/1e3),e=O(d/60),f=O(e/60),g=O(f/24),h=O(g/365),i=45>d&&["s",d]||1===e&&["m"]||45>e&&["mm",e]||1===f&&["h"]||22>f&&["hh",f]||1===g&&["d"]||25>=g&&["dd",g]||45>=g&&["M"]||345>g&&["MM",O(g/30)]||1===h&&["y"]||["yy",h];return i[2]=b,i[3]=a>0,i[4]=c,E.apply({},i)}function G(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=L(a).add("d",f),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function H(a){var b=a._i,c=a._f;return null===b||""===b?null:("string"==typeof b&&(a._i=b=p().preparse(b)),L.isMoment(b)?(a=g({},b),a._d=new Date(+b._d)):c?k(c)?B(a):A(a):D(a),new e(a))}function I(a,b){L.fn[a]=L.fn[a+"s"]=function(a){var c=this._isUTC?"UTC":"";return null!=a?(this._d["set"+c+b](a),L.updateOffset(this),this):this._d["get"+c+b]()}}function J(a){L.duration.fn[a]=function(){return this._data[a]}}function K(a,b){L.duration.fn["as"+a]=function(){return+this/b}}for(var L,M,N="2.2.1",O=Math.round,P={},Q="undefined"!=typeof module&&module.exports,R=/^\/?Date\((\-?\d+)/i,S=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)\:(\d+)\.?(\d{3})?/,T=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,U=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,V=/\d\d?/,W=/\d{1,3}/,X=/\d{3}/,Y=/\d{1,4}/,Z=/[+\-]?\d{1,6}/,$=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,_=/Z|[\+\-]\d\d:?\d\d/i,ab=/T/i,bb=/[\+\-]?\d+(\.\d{1,3})?/,cb=/^\s*\d{4}-\d\d-\d\d((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,db="YYYY-MM-DDTHH:mm:ssZ",eb=[["HH:mm:ss.S",/(T| )\d\d:\d\d:\d\d\.\d{1,3}/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],fb=/([\+\-]|\d\d)/gi,gb="Date|Hours|Minutes|Seconds|Milliseconds".split("|"),hb={Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6},ib={ms:"millisecond",s:"second",m:"minute",h:"hour",d:"day",w:"week",W:"isoweek",M:"month",y:"year"},jb={},kb="DDD w W M D d".split(" "),lb="M D H h m s w W".split(" "),mb={M:function(){return this.month()+1},MMM:function(a){return this.lang().monthsShort(this,a)},MMMM:function(a){return this.lang().months(this,a)},D:function(){return this.date()},DDD:function(){return this.dayOfYear()},d:function(){return this.day()},dd:function(a){return this.lang().weekdaysMin(this,a)},ddd:function(a){return this.lang().weekdaysShort(this,a)},dddd:function(a){return this.lang().weekdays(this,a)},w:function(){return this.week()},W:function(){return this.isoWeek()},YY:function(){return i(this.year()%100,2)},YYYY:function(){return i(this.year(),4)},YYYYY:function(){return i(this.year(),5)},gg:function(){return i(this.weekYear()%100,2)},gggg:function(){return this.weekYear()},ggggg:function(){return i(this.weekYear(),5)},GG:function(){return i(this.isoWeekYear()%100,2)},GGGG:function(){return this.isoWeekYear()},GGGGG:function(){return i(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.lang().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.lang().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return~~(this.milliseconds()/100)},SS:function(){return i(~~(this.milliseconds()/10),2)},SSS:function(){return i(this.milliseconds(),3)},Z:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+i(~~(a/60),2)+":"+i(~~a%60,2)},ZZ:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+i(~~(10*a/6),4)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},X:function(){return this.unix()}};kb.length;)M=kb.pop(),mb[M+"o"]=c(mb[M],M);for(;lb.length;)M=lb.pop(),mb[M+M]=b(mb[M],2);for(mb.DDDD=b(mb.DDD,3),g(d.prototype,{set:function(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(a){return this._months[a.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(a){return this._monthsShort[a.month()]},monthsParse:function(a){var b,c,d;for(this._monthsParse||(this._monthsParse=[]),b=0;12>b;b++)if(this._monthsParse[b]||(c=L.utc([2e3,b]),d="^"+this.months(c,"")+"|^"+this.monthsShort(c,""),this._monthsParse[b]=new RegExp(d.replace(".",""),"i")),this._monthsParse[b].test(a))return b},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(a){return this._weekdays[a.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(a){return this._weekdaysShort[a.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(a){return this._weekdaysMin[a.day()]},weekdaysParse:function(a){var b,c,d;for(this._weekdaysParse||(this._weekdaysParse=[]),b=0;7>b;b++)if(this._weekdaysParse[b]||(c=L([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b},_longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D YYYY",LLL:"MMMM D YYYY LT",LLLL:"dddd, MMMM D YYYY LT"},longDateFormat:function(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b},isPM:function(a){return"p"===(a+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(a,b){var c=this._calendar[a];return"function"==typeof c?c.apply(b):c},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)},pastFuture:function(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)},ordinal:function(a){return this._ordinal.replace("%d",a)},_ordinal:"%d",preparse:function(a){return a},postformat:function(a){return a},week:function(a){return G(a,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6}}),L=function(a,b,c){return H({_i:a,_f:b,_l:c,_isUTC:!1})},L.utc=function(a,b,c){return H({_useUTC:!0,_isUTC:!0,_l:c,_i:a,_f:b}).utc()},L.unix=function(a){return L(1e3*a)},L.duration=function(a,b){var c,d,e=L.isDuration(a),g="number"==typeof a,h=e?a._input:g?{}:a,i=S.exec(a);return g?b?h[b]=a:h.milliseconds=a:i&&(c="-"===i[1]?-1:1,h={y:0,d:~~i[2]*c,h:~~i[3]*c,m:~~i[4]*c,s:~~i[5]*c,ms:~~i[6]*c}),d=new f(h),e&&a.hasOwnProperty("_lang")&&(d._lang=a._lang),d},L.version=N,L.defaultFormat=db,L.updateOffset=function(){},L.lang=function(a,b){return a?(a=a.toLowerCase(),a=a.replace("_","-"),b?n(a,b):null===b?(o(a),a="en"):P[a]||p(a),L.duration.fn._lang=L.fn._lang=p(a),void 0):L.fn._lang._abbr},L.langData=function(a){return a&&a._lang&&a._lang._abbr&&(a=a._lang._abbr),p(a)},L.isMoment=function(a){return a instanceof e},L.isDuration=function(a){return a instanceof f},g(L.fn=e.prototype,{clone:function(){return L(this)},valueOf:function(){return+this._d+6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){return s(L(this).utc(),"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},toArray:function(){var a=this;return[a.year(),a.month(),a.date(),a.hours(),a.minutes(),a.seconds(),a.milliseconds()]},isValid:function(){return null==this._isValid&&(this._isValid=this._a?!l(this._a,(this._isUTC?L.utc(this._a):L(this._a)).toArray()):!isNaN(this._d.getTime())),!!this._isValid},invalidAt:function(){var a,b=this._a,c=(this._isUTC?L.utc(this._a):L(this._a)).toArray();for(a=6;a>=0&&b[a]===c[a];--a);return a},utc:function(){return this.zone(0)},local:function(){return this.zone(0),this._isUTC=!1,this},format:function(a){var b=s(this,a||L.defaultFormat);return this.lang().postformat(b)},add:function(a,b){var c;return c="string"==typeof a?L.duration(+b,a):L.duration(a,b),j(this,c,1),this},subtract:function(a,b){var c;return c="string"==typeof a?L.duration(+b,a):L.duration(a,b),j(this,c,-1),this},diff:function(a,b,c){var d,e,f=this._isUTC?L(a).zone(this._offset||0):L(a).local(),g=6e4*(this.zone()-f.zone());return b=m(b),"year"===b||"month"===b?(d=432e5*(this.daysInMonth()+f.daysInMonth()),e=12*(this.year()-f.year())+(this.month()-f.month()),e+=(this-L(this).startOf("month")-(f-L(f).startOf("month")))/d,e-=6e4*(this.zone()-L(this).startOf("month").zone()-(f.zone()-L(f).startOf("month").zone()))/d,"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:h(e)},from:function(a,b){return L.duration(this.diff(a)).lang(this.lang()._abbr).humanize(!b)},fromNow:function(a){return this.from(L(),a)},calendar:function(){var a=this.diff(L().zone(this.zone()).startOf("day"),"days",!0),b=-6>a?"sameElse":-1>a?"lastWeek":0>a?"lastDay":1>a?"sameDay":2>a?"nextDay":7>a?"nextWeek":"sameElse";return this.format(this.lang().calendar(b,this))},isLeapYear:function(){var a=this.year();return 0===a%4&&0!==a%100||0===a%400},isDST:function(){return this.zone()+L(a).startOf(b)},isBefore:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)<+L(a).startOf(b)},isSame:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)===+L(a).startOf(b)},min:function(a){return a=L.apply(null,arguments),this>a?this:a},max:function(a){return a=L.apply(null,arguments),a>this?this:a},zone:function(a){var b=this._offset||0;return null==a?this._isUTC?b:this._d.getTimezoneOffset():("string"==typeof a&&(a=v(a)),Math.abs(a)<16&&(a=60*a),this._offset=a,this._isUTC=!0,b!==a&&j(this,L.duration(b-a,"m"),1,!0),this)},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},hasAlignedHourOffset:function(a){return a=a?L(a).zone():0,0===(this.zone()-a)%60},daysInMonth:function(){return L.utc([this.year(),this.month()+1,0]).date()},dayOfYear:function(a){var b=O((L(this).startOf("day")-L(this).startOf("year"))/864e5)+1;return null==a?b:this.add("d",a-b)},weekYear:function(a){var b=G(this,this.lang()._week.dow,this.lang()._week.doy).year;return null==a?b:this.add("y",a-b)},isoWeekYear:function(a){var b=G(this,1,4).year;return null==a?b:this.add("y",a-b)},week:function(a){var b=this.lang().week(this);return null==a?b:this.add("d",7*(a-b))},isoWeek:function(a){var b=G(this,1,4).week;return null==a?b:this.add("d",7*(a-b))},weekday:function(a){var b=(this._d.getDay()+7-this.lang()._week.dow)%7;return null==a?b:this.add("d",a-b)},isoWeekday:function(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)},get:function(a){return a=m(a),this[a.toLowerCase()]()},set:function(a,b){a=m(a),this[a.toLowerCase()](b)},lang:function(b){return b===a?this._lang:(this._lang=p(b),this)}}),M=0;M-0.00001?a+.5*a*a:Math.exp(a)-1},science.functor=function(a){return typeof a=="function"?a:function(){return a}},science.hypot=function(a,b){a=Math.abs(a),b=Math.abs(b);var c,d;a>b?(c=a,d=b):(c=b,d=a);var e=d/c;return c*Math.sqrt(1+e*e)},science.quadratic=function(){function b(b,c,d){var e=c*c-4*b*d;return e>0?(e=Math.sqrt(e)/(2*b),a?[{r:-c-e,i:0},{r:-c+e,i:0}]:[-c-e,-c+e]):e===0?(e=-c/(2*b),a?[{r:e,i:0}]:[e]):a?(e=Math.sqrt(-e)/(2*b),[{r:-c,i:-e},{r:-c,i:e}]):[]}var a=!1;return b.complex=function(c){return arguments.length?(a=c,b):a},b},science.zeroes=function(a){var b=-1,c=[];if(arguments.length===1)while(++b0;f--){var g=0,h=0;for(var i=0;i0&&(k=-k),b[f]=g*k,h-=j*k,a[f-1]=j-k;for(var e=0;ei){var k=0;do{k++;var l=a[i],m=(a[i+1]-l)/(2*b[i]),n=science.hypot(m,1);m<0&&(n=-n),a[i]=b[i]/(m+n),a[i+1]=b[i]*(m+n);var o=a[i+1],p=l-a[i];for(var e=i+2;e=i;e--){s=r,r=q,v=u,l=q*b[e],p=q*m,n=science.hypot(m,b[e]),b[e+1]=u*n,u=b[e]/n,q=m/n,m=q*a[e]-u*l,a[e+1]=p+u*(q*l+u*a[e]);for(var w=0;wh*g)}a[i]=a[i]+f,b[i]=0}for(var e=0;e=g;i--)d[i]=a[i][g-1]/h,j+=d[i]*d[i];var k=Math.sqrt(j);d[g]>0&&(k=-k),j-=d[g]*k,d[g]=d[g]-k;for(var l=g;l=g;i--)m+=d[i]*a[i][l];m/=j;for(var i=g;i<=f;i++)a[i][l]-=m*d[i]}for(var i=0;i<=f;i++){var m=0;for(var l=f;l>=g;l--)m+=d[l]*a[i][l];m/=j;for(var l=g;l<=f;l++)a[i][l]-=m*d[l]}d[g]=h*d[g],a[g][g-1]=h*k}}for(var i=0;i=e+1;g--)if(a[g][g-1]!==0){for(var i=g+1;i<=f;i++)d[i]=a[i][g-1];for(var l=g;l<=f;l++){var k=0;for(var i=g;i<=f;i++)k+=d[i]*b[i][l];k=k/d[g]/a[g][g-1];for(var i=g;i<=f;i++)b[i][l]+=k*d[i]}}}function e(a,b,c,d){var e=c.length,g=e-1,h=0,i=e-1,j=1e-12,k=0,l=0,m=0,n=0,o=0,p=0,q,r,s,t,u=0;for(var v=0;vi)a[v]=c[v][v],b[v]=0;for(var w=Math.max(v-1,0);w=h){var y=g;while(y>h){o=Math.abs(c[y-1][y-1])+Math.abs(c[y][y]),o===0&&(o=u);if(Math.abs(c[y][y-1])=0){p=l+(l>=0?p:-p),a[g-1]=s+p,a[g]=a[g-1],p!==0&&(a[g]=s-r/p),b[g-1]=0,b[g]=0,s=c[g][g-1],o=Math.abs(s)+Math.abs(p),l=s/o,m=p/o,n=Math.sqrt(l*l+m*m),l/=n,m/=n;for(var w=g-1;w0){o=Math.sqrt(o),t=y){p=c[z][z],n=s-p,o=t-p,l=(n*o-r)/c[z+1][z]+c[z][z+1],m=c[z+1][z+1]-p-n-o,n=c[z+2][z+1],o=Math.abs(l)+Math.abs(m)+Math.abs(n),l/=o,m/=o,n/=o;if(z==y)break;if(Math.abs(c[z][z-1])*(Math.abs(m)+Math.abs(n))z+2&&(c[v][v-3]=0);for(var A=z;A<=g-1;A++){var B=A!=g-1;A!=z&&(l=c[A][A-1],m=c[A+1][A-1],n=B?c[A+2][A-1]:0,s=Math.abs(l)+Math.abs(m)+Math.abs(n),s!=0&&(l/=s,m/=s,n/=s));if(s==0)break;o=Math.sqrt(l*l+m*m+n*n),l<0&&(o=-o);if(o!=0){A!=z?c[A][A-1]=-o*s:y!=z&&(c[A][A-1]=-c[A][A-1]),l+=o,s=l/o,t=m/o,p=n/o,m/=l,n/=l;for(var w=A;w=0;g--){l=a[g],m=b[g];if(m==0){var y=g;c[g][g]=1;for(var v=g-1;v>=0;v--){r=c[v][v]-l,n=0;for(var w=y;w<=g;w++)n+=c[v][w]*c[w][g];if(b[v]<0)p=r,o=n;else{y=v,b[v]===0?c[v][g]=-n/(r!==0?r:j*u):(s=c[v][v+1],t=c[v+1][v],m=(a[v]-l)*(a[v]-l)+b[v]*b[v],q=(s*o-p*n)/m,c[v][g]=q,Math.abs(s)>Math.abs(p)?c[v+1][g]=(-n-r*q)/s:c[v+1][g]=(-o-t*q)/p),q=Math.abs(c[v][g]);if(j*q*q>1)for(var w=v;w<=g;w++)c[w][g]=c[w][g]/q}}}else if(m<0){var y=g-1;if(Math.abs(c[g][g-1])>Math.abs(c[g-1][g]))c[g-1][g-1]=m/c[g][g-1],c[g-1][g]=-(c[g][g]-l)/c[g][g-1];else{var C=f(0,-c[g-1][g],c[g-1][g-1]-l,m);c[g-1][g-1]=C[0],c[g-1][g]=C[1]}c[g][g-1]=0,c[g][g]=1;for(var v=g-2;v>=0;v--){var D=0,E=0,F,G;for(var w=y;w<=g;w++)D+=c[v][w]*c[w][g-1],E+=c[v][w]*c[w][g];r=c[v][v]-l;if(b[v]<0)p=r,n=D,o=E;else{y=v;if(b[v]==0){var C=f(-D,-E,r,m);c[v][g-1]=C[0],c[v][g]=C[1]}else{s=c[v][v+1],t=c[v+1][v],F=(a[v]-l)*(a[v]-l)+b[v]*b[v]-m*m,G=(a[v]-l)*2*m,F==0&G==0&&(F=j*u*(Math.abs(r)+Math.abs(m)+Math.abs(s)+Math.abs(t)+Math.abs(p)));var C=f(s*n-p*D+m*E,s*o-p*E-m*D,F,G);c[v][g-1]=C[0],c[v][g]=C[1];if(Math.abs(s)>Math.abs(p)+Math.abs(m))c[v+1][g-1]=(-D-r*c[v][g-1]+m*c[v][g])/s,c[v+1][g]=(-E-r*c[v][g]-m*c[v][g-1])/s;else{var C=f(-n-t*c[v][g-1],-o-t*c[v][g],p,m);c[v+1][g-1]=C[0],c[v+1][g]=C[1]}}q=Math.max(Math.abs(c[v][g-1]),Math.abs(c[v][g]));if(j*q*q>1)for(var w=v;w<=g;w++)c[w][g-1]=c[w][g-1]/q,c[w][g]=c[w][g]/q}}}}for(var v=0;vi)for(var w=v;w=h;w--)for(var v=h;v<=i;v++){p=0;for(var A=h;A<=Math.min(w,i);A++)p+=d[v][A]*c[A][w];d[v][w]=p}}function f(a,b,c,d){if(Math.abs(c)>Math.abs(d)){var e=d/c,f=c+e*d;return[(a+e*b)/f,(b-e*a)/f]}var e=c/d,f=d+e*c;return[(e*a+b)/f,(e*b-a)/f]}science.lin={},science.lin.decompose=function(){function a(a){var f=a.length,g=[],h=[],i=[];for(var j=0;j0?j+1:j-1]=i[j]}return{D:n,V:g}}return a},science.lin.cross=function(a,b){return[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]]},science.lin.dot=function(a,b){var c=0,d=-1,e=Math.min(a.length,b.length);while(++dMath.abs(a[h][e])&&(h=f);var i=a[e];a[e]=a[h],a[h]=i;if(Math.abs(a[e][e])<=b)return!1;f=e;while(++f=0){var j=a[e][e];f=-1;while(++f=e)a[f][g]-=a[e][g]*a[f][e]/j}a[e][e]/=j,g=c-1;while(++gh[k][q]&&(h[q][j]=h[j][q]=h[k][q]);break;case"complete":h[j][q]0&&h(d,j,l,r);var t=r[0],u=r[1],v=d[l]-d[t]>d[u]-d[l]?t:u,w=0,x=0,y=0,z=0,A=0,B=Math.abs(1/(d[v]-s));for(var C=t;C<=u;++C){var D=d[C],E=i[C],F=C=1?0:(G=1-Q*Q)*G}return n}var a=.3,b=2,c=1e-12;return d.bandwidth=function(b){return arguments.length?(a=b,d):b},d.robustnessIterations=function(a){return arguments.length?(b=a,d):a},d.accuracy=function(a){return arguments.length?(c=a,d):a},d},science.stats.mean=function(a){var b=a.length;if(b===0)return NaN;var c=0,d=-1;while(++dd&&(d=h,c=[g]);if(c.length===1)return c[0]},science.stats.quantiles=function(a,b){a=a.slice().sort(science.ascending);var c=a.length-1;return b.map(function(b){if(b===0)return a[0];if(b===1)return a[c];var d=1+b*c,e=Math.floor(d),f=d-e,g=a[e-1];return f===0?g:g+f*(a[e]-g)})},science.stats.variance=function(a){var b=a.length;if(b<1)return NaN;if(b===1)return 0;var c=science.stats.mean(a),d=-1,e=0;while(++d=1||f===0);return b+c*d*Math.sqrt(-2*Math.log(f)/f)}var a=Math.random,b=0,c=1,d=1;return e.pdf=function(a){return a=(a-b)/c,science_stats_distribution_gaussianConstant*Math.exp(-0.5*a*a)/c},e.cdf=function(a){return a=(a-b)/c,.5*(1+science.stats.erf(a/Math.SQRT2))},e.mean=function(a){return arguments.length?(b=+a,e):b},e.variance=function(a){return arguments.length?(c=Math.sqrt(d=+a),e):d},e.random=function(b){return arguments.length?(a=b,e):a},e},science_stats_distribution_gaussianConstant=1/Math.sqrt(2*Math.PI)}(this)})(this); +/*jslint indent: 4, plusplus: true, nomen: true */ +/** + * MongoDB - distinct2.js + * + * Version: 1.5 + * Date: December 12, 2012 + * Project: http://skratchdot.com/projects/mongodb-distinct2/ + * Source Code: https://github.com/skratchdot/mongodb-distinct2/ + * Issues: https://github.com/skratchdot/mongodb-distinct2/issues/ + * Dependencies: MongoDB v1.8+ + * JSON2.js (https://github.com/douglascrockford/JSON-js) + * + * Copyright (c) 2012 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + 'use strict'; + + // config variables + var currentDate, + currentTick = (new Date()).getTime(), + previousTick = (new Date()).getTime(), + statusIntervalInMs = 10000, + // functions + isArray, + getFromKeyString, + getHashKey, + printStatus, + setStatusInterval; + + /** + * Same behavior as Array.isArray() + * @function + * @name isArray + * @private + * @param obj {*} The object to test + * @returns {boolean} Will return true of obj is an array, otherwise will return false + */ + isArray = function (obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; + }; + + /** + * @function + * @name getFromKeyString + * @private + * @param obj {object} The object to search + * @param keyString {string} A dot delimited string path + * @returns {object|undefined} If we find the path provide by keyString, we will return the value at that path + */ + getFromKeyString = function (obj, keyString) { + var arr, i; + if (typeof keyString === 'string') { + arr = keyString.split('.'); + for (i = 0; i < arr.length; i++) { + if (obj && typeof obj === 'object' && obj.hasOwnProperty(arr[i])) { + obj = obj[arr[i]]; + } else { + return; + } + } + return obj; + } + }; + + /** + * @function + * @name printStatus + * @private + * @param currentDocNum {number} - Number of the current document being processed + * @param numDocs {number} - Total number of documents being processed + * @param distinctCount {number} - Total number of distinct items found so far + */ + printStatus = function (currentDocNum, numDocs, distinctCount) { + // Output some debugging info if needed + if (statusIntervalInMs > 0) { + currentDate = new Date(); + currentTick = currentDate.getTime(); + if (currentTick - previousTick > statusIntervalInMs) { + print('Processed ' + currentDocNum + ' of ' + numDocs + ' document(s) and found ' + distinctCount + ' distinct items at ' + currentDate); + previousTick = currentTick; + } + } + }; + + /** + * @function + * @name setStatusInterval + * @private + * @param intervalInMs {number} Will print out a status message after this many + * milliseconds. If a non-positive number is passed in, + * then no status messages will be printed. + */ + setStatusInterval = function (intervalInMs) { + if (typeof intervalInMs === 'number') { + statusIntervalInMs = intervalInMs; + } + }; + + /** + * @function + * @name distinct2 + * @memberOf DBQuery + * @param keys {string|array} The array of dot delimited keys to get the distinct values for + * @param count {boolean} Whether or not to append + * @returns {array} If keys is a string, and count is false, then we behave like .distinct(). + * If keys is a positive sized array, we will return an array of arrays. + * If count is true, we will return an array of arrays where the last value is the count. + */ + DBQuery.prototype.distinct2 = function (keys, count) { + var i = 0, + currentDocNum = 0, + numDocs = this.size(), + distinctCount = 0, + returnArray = [], + tempArray = [], + arrayOfValues = false, + dataOrder = [], + data = {}; + + // if passed a string, convert it into an array + if (typeof keys === 'string') { + keys = [keys]; + } + + // if keys is not a positive sized array by now, do nothing + if (!isArray(keys) || keys.length === 0) { + return returnArray; + } + + // update tick for printing status line + previousTick = (new Date()).getTime(); + + // populate data object + this.forEach(function (obj) { + var i, values = [], key = '', isDefined = false; + for (i = 0; i < keys.length; i++) { + values[i] = getFromKeyString(obj, keys[i]); + if (typeof values[i] !== 'undefined') { + isDefined = true; + } + } + if (isDefined) { + key = getHashKey(values); + if (data.hasOwnProperty(key)) { + data[key].count = data[key].count + 1; + } else { + dataOrder.push(key); + data[key] = { + values : values, + count : 1 + }; + } + } + // print status info + printStatus(++currentDocNum, numDocs, dataOrder.length); + }); + + // should we return an array of values? + if (keys.length === 1 && !count) { + arrayOfValues = true; + } + + for (i = 0; i < dataOrder.length; i++) { + if (arrayOfValues) { // we return an array of values + returnArray.push(data[dataOrder[i]].values[0]); + } else { // we return an array of arrays + tempArray = data[dataOrder[i]].values; + if (count) { + tempArray.push(data[dataOrder[i]].count); + } + returnArray.push(tempArray); + } + } + + return returnArray; + }; + + /** + * @function + * @name distinct2 + * @memberOf DBCollection + * @param keys {string|array} The array of dot delimited keys to get the distinct values for + * @param count {boolean} Whether or not to append + * @returns {array} If keys is a string, and count is false, then we behave like .distinct(). + * If keys is a positive sized array, we will return an array of arrays. + * If count is true, we will return an array of arrays where the last value is the count. + */ + DBCollection.prototype.distinct2 = function (keys, count) { + var fields = {}, i, excludeId = true; + if (typeof keys === 'string') { + keys = [keys]; + } + if (!isArray(keys)) { + keys = []; + } + for (i = 0; i < keys.length; i++) { + fields[keys[i]] = 1; + if (keys[i] === '_id') { + excludeId = false; + } + } + if (!excludeId) { + fields._id = 0; + } + return this.find({}, fields).distinct2(keys, count); + }; + + // Attach setStatusInterval to both versions of distinct2 + DBQuery.prototype.distinct2.setStatusInterval = setStatusInterval; + DBCollection.prototype.distinct2.setStatusInterval = setStatusInterval; + + // set the correct getHashKey function + if (typeof JSON !== 'undefined' && typeof JSON.stringify === 'function') { + getHashKey = JSON.stringify; + } else if (typeof tojson === 'function') { + getHashKey = tojson; + } else { + getHashKey = function (obj) { + return obj; + }; + } +}()); +/*jslint devel: false, nomen: true, maxerr: 50, indent: 4 */ +/** + * MongoDB - distinct-types.js + * + * Version: 1.0 + * Date: April 29, 2012 + * Project: http://skratchdot.github.com/mongodb-distinct-types/ + * Source Code: https://github.com/skratchdot/mongodb-distinct-types/ + * Issues: https://github.com/skratchdot/mongodb-distinct-types/issues/ + * Dependencies: MongoDB v1.8+ + * + * Description: + * + * Similar to the db.myCollection.distinct() function, distinctTypes() will return + * "types" rather than "values". To accomplish this, it adds the following + * function to the DBCollection prototype: + * + * DBCollection.prototype.distinctTypes = function (keyString, query, limit, skip) {}; + * + * Usage: + * + * db.users.distinctTypes('name'); // we hope this would return ['bson'] not ['bson','string'] + * db.users.distinctTypes('name.first'); // should return ['string'] + * db.users.distinctTypes('address.phone'); // should return ['string'] + * db.users.distinctTypes('address.phone', {'name.first':'Bob'}); // only search documents that have { 'name.first' : 'Bob' } + * db.users.distinctTypes('address.phone', {}, 10); // only search the first 10 documents + * db.users.distinctTypes('address.phone', {}, 10, 5); // only search documents 10-15 + * + * Caveats: + * + * By design, distinctTypes() returns 'bson' rather than 'object'. + * It will return 'numberlong' rather than 'number', etc. + * + * Copyright (c) 2012 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + 'use strict'; + + var getType = function (obj) { + return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); + }, + getFromKeyString = function (obj, keyString) { + var returnValue = { + value : null, + found : false + }, + dotIndex = keyString.indexOf('.'), + currentKey = '', + newKeyString = ''; + if (dotIndex < 0) { + if (obj.hasOwnProperty(keyString)) { + returnValue = { + value : obj[keyString], + found : true + }; + } + } else { + currentKey = keyString.substr(0, dotIndex); + newKeyString = keyString.substr(dotIndex + 1); + if (obj.hasOwnProperty(currentKey)) { + returnValue = getFromKeyString(obj[currentKey], newKeyString); + } + } + return returnValue; + }; + + /** + * @function + * @name distinctTypes + * @memberOf DBCollection + * @param {string} keyString The key (using dot notation) to return distinct types for + * @param {object} query A mongo query in the same format that db.myCollection.find() accepts. + * @param {number} limit Limit the result set by this number. + * @param {number} skip The number of records to skip. + */ + DBCollection.prototype.distinctTypes = function (keyString, query, limit, skip) { + var fields = {}, + queryResult = null, + result = []; + if (typeof keyString !== 'string') { + keyString = ''; + } + fields[keyString] = 1; + queryResult = new DBQuery(this._mongo, this._db, this, this._fullName, + this._massageObject(query), fields, limit, skip).forEach(function (doc) { + var type = '', currentValue = getFromKeyString(doc, keyString); + if (currentValue.found) { + type = getType(currentValue.value); + if (result.indexOf(type) === -1) { + result.push(type); + } + } + }); + return result; + }; +}()); +/*jslint devel: false, unparam: true, nomen: true, maxerr: 50, indent: 4, plusplus: true */ +/** + * MongoDB - flatten.js + * + * Version: 1.3 + * Date: October 22, 2012 + * Project: http://skratchdot.com/projects/mongodb-flatten/ + * Source Code: https://github.com/skratchdot/mongodb-flatten/ + * Issues: https://github.com/skratchdot/mongodb-flatten/issues/ + * Dependencies: MongoDB v1.8+ + * + * Copyright (c) 2012 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + 'use strict'; + + var currentDb, emitKeys, insertKey, flatten, + statusDelayInMs = 10000, + currentId = null, currentDate = null, currentTick = null, previousTick = null; + + /** + * @function + * @name insertKey + * @memberOf anonymous + * @param {DBCollection} collection - the collection we are storing our flattened data in + * @param {ObjectId/object} id - the id of the document being flattened + * @param {string} key - the flattened key + * @param {any} value - the value of the flattened key + */ + insertKey = function (collection, id, key, value) { + // Increment our currentId + currentId = currentId + 1; + + // Insert document into our collection + collection.insert({ + '_id' : currentId, + 'i' : id, + 'k' : key, + 'v' : value + }); + }; + + /** + * @function + * @name emitKeys + * @memberOf anonymous + * @param {DBCollection} collection - the collection we are storing our flattened data in + * @param {ObjectId/object} id - the id of the document being flattened + * @param {object} node - the current node being flattened. initially this is the entire document + * @param {string} keyString - the current key/path. will be built recursively. initially an empty string. + */ + emitKeys = function (collection, id, node, keyString) { + var key, newKey, type = typeof (node); + if (type === 'object' || type === 'array') { + for (key in node) { + if (node.hasOwnProperty(key)) { + newKey = (keyString === '' ? key : keyString + '.' + key); + if (newKey === '_id') { + insertKey(collection, id, '_id', node[key]); + } else { + emitKeys(collection, id, node[key], newKey); + } + } + } + } else { + insertKey(collection, id, keyString, node); + } + }; + + /** + * @function + * @name flatten + * @memberOf anonymous + * @param {DBQuery} query - the current DBQuery object/cursor + * @param {string} collectionName - the name of the collection in which the results will be stored + */ + flatten = function (query, collectionName) { + var collection, i, numDocs = query.size(), currentDoc, currentDocNum; + + // If an invalid name is passed, create a temporary collection + if (typeof collectionName !== 'string' || collectionName.length === 0) { + collectionName = 'temp.flatten_' + new Date().getTime(); + } + + // Print some debug info + print('Flattening ' + numDocs + ' document(s) into the "' + collectionName + '" collection.'); + + // Get our collection + collection = query._db.getCollection(collectionName); + + // Empty our collection + collection.drop(); + + // Index our collection to speed up lookups + collection.ensureIndex({i : 1}); + collection.ensureIndex({k : 1}); + collection.ensureIndex({v : 1}); + + // Initialize some global counters/variables + previousTick = new Date().getTime(); + currentId = 0; + currentDocNum = 0; + + // Loop through all our objects, inserting records into our collection + while (query.hasNext()) { + // The current document we are processing + currentDoc = query.next(); + currentDocNum++; + + // Output some debugging info if needed + currentDate = new Date(); + currentTick = currentDate.getTime(); + if (currentTick - previousTick > statusDelayInMs) { + print('Flattened ' + currentDocNum + ' of ' + numDocs + ' document(s) and ' + currentId + ' key(s) at ' + currentDate); + previousTick = currentTick; + } + + // There's a chance documents don't have + // _id values (capped collections, internal collections) + if (!currentDoc.hasOwnProperty('_id')) { + currentDoc._id = 'unknown'; + } + + // Insert key/value pairs into our new collection + emitKeys(collection, currentDoc._id, currentDoc, ''); + } + + return collection; + }; + + /** + * @function + * @name flatten + * @memberOf DBQuery + * @param {string} collectionName - the name of the collection in which the results will be stored + */ + DBQuery.prototype.flatten = function (collectionName) { + return flatten(this, collectionName); + }; + + /** + * @function + * @name flatten + * @memberOf DBCollection + * @param {string} collectionName - the name of the collection in which the results will be stored + */ + DBCollection.prototype.flatten = function (collectionName) { + return this.find().flatten(collectionName); + }; + +}()); +/*jslint devel: false, nomen: true, unparam: true, plusplus: true, maxerr: 50, indent: 4 */ +/** + * MongoDB - schema.js + * + * Version: 1.1 + * Date: May 28, 2012 + * Project: http://skratchdot.github.com/mongodb-schema/ + * Source Code: https://github.com/skratchdot/mongodb-schema/ + * Issues: https://github.com/skratchdot/mongodb-schema/issues/ + * Dependencies: MongoDB v1.8+ + * + * Description: + * + * This is a schema analysis tool for MongoDB. It accomplishes this by + * extending the mongo shell, and providing a new function called schema() + * with the following signature: + * + * DBCollection.prototype.schema = function (optionsOrOutString) + * + * Usage: + * + * The schema() function accepts all the same parameters that the mapReduce() function + * does. It adds/modifies the following 4 parameters that can be used as well: + * + * wildcards - array (default: []) + * By using the $, you can combine report results. + * For instance: '$' will group all top level keys and + * 'foo.$.bar' will combine 'foo.baz.bar' and 'foo.bar.bar' + * + * arraysAreWildcards - boolean (default: true) + * When true, 'foo.0.bar' and 'foo.1.bar' will be + * combined into 'foo.$.bar' + * When false, all array keys will be reported + * + * fields - object (default: {}) + * Similar to the usage in find(). You can pick the + * fields to include or exclude. Currently, you cannot + * pass in nested structures, you need to pass in dot notation keys. + * + * limit - number (default: 50) + * Behaves the same as the limit in mapReduce(), but defaults to 50. + * You can pass in 0 or -1 to process all documents. + * + * Return schema results inline + * db.users.schema(); + * + * Create and store schema results in the 'users_schema' collection + * db.users.schema('users_schema'); // Option 1 + * db.users.schema({out:'users_schema'}); // Option 2 + * db.users.schema({out:{replace:'users_schema'}}); // Option 3 + * + * Only report on the key: 'name.first' + * db.users.schema({fields:{'name.first':1}}); + * + * Report on everything except 'name.first' + * db.users.schema({fields:{'name.first':-1}}); + * + * Combine the 'name.first' and 'name.last' keys into 'name.$' + * db.users.schema({wildcards:['name.$']}); + * + * Don't treat arrays as a wildcard + * db.users.schema({arraysAreWildcards:false}); + * + * Process 50 documents + * db.users.schema(); + * + * Process all documents + * db.users.schema({limit:-1}); + * + * Caveats: + * + * By design, schema() returns 'bson' rather than 'object'. + * It will return 'numberlong' rather than 'number', etc. + * + * Inspired by: + * + * Variety: https://github.com/JamesCropcho/variety + * + * Copyright (c) 2012 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + 'use strict'; + + /** + * You can pass in the same options object that mapReduce() accepts. Schema has the following + * defaults for options: + * + * options.out = { inline : 1 }; + * options.limit = 50; + * + * You can pass in an options.limit value of 0 or -1 to parse _all_ documents. + * + * @function + * @name flatten + * @memberOf DBCollection + * @param {object} optionsOrOutString This function accepts the same options as mapReduce + */ + DBCollection.prototype.schema = function (optionsOrOutString) { + var statCount = 0, wildcards = [], arraysAreWildcards = true, + field, fields = {}, usePositiveFields = false, useNegativeFields = false, + getType, getNewKeyString, getKeyInfo, map, reduce, finalize, options = { limit : 50 }; + + /** + * @function + * @name getType + * @private + * @param {object} obj The object to inspect + */ + getType = function (obj) { + return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); + }; + + /** + * @function + * @name getNewKeyString + * @private + * @param {string} key The current key + * @param {string} keyString The object to inspect + */ + getNewKeyString = function (key, keyString) { + var i, j, keyArray, newKeyString, success, wc; + newKeyString = (keyString === '' ? key : keyString + '.' + key); + if (wildcards.length > 0) { + keyArray = newKeyString.split('.'); + for (i = 0; i < wildcards.length; i++) { + wc = wildcards[i].split('.'); + if (keyArray.length === wc.length) { + success = true; + for (j = 0; success && j <= wc.length; j++) { + if (wc[j] !== '$' && wc[j] !== keyArray[j]) { + success = false; + } + } + if (success) { + return wildcards[i]; + } + } + } + } + return newKeyString; + }; + + /** + * @function + * @name getKeyInfo + * @private + * @param {object} node The node from which we generate our keys + * @param {string} keyString A string representing the current key 'path' + * @param {object} keyInfo The struct that contains all our 'paths' as the key, and a count for it's value + */ + getKeyInfo = function (node, keyString, keyInfo) { + var key, newKeyString, type, useArrayWildcard = false; + + // Store the mongo type. 'bson' instead of 'object', etc + type = getType(node); + + // We need to handle objects and arrays by calling getKeyInfo() recursively + if (['array', 'bson', 'object'].indexOf(type) >= 0) { + + // Set the flag to be used in our for loop below + if (type === 'array' && arraysAreWildcards === true) { + useArrayWildcard = true; + } + + // Loop through each key + for (key in node) { + if (node.hasOwnProperty(key)) { + if (useArrayWildcard) { + newKeyString = keyString + '.$'; + } else { + newKeyString = getNewKeyString(key, keyString); + } + keyInfo = getKeyInfo(node[key], newKeyString, keyInfo); + } + } + + } + + // We don't need to emit this key + // Using a long statement to pass jslint + // there are 3 parts to this: + // 1: empty key + // 2: usePostiveFields is true, and the current key is not valid + // 3: useNegativeFields is true, and the current key exists in fields (and is -1) + if (keyString === '' || (usePositiveFields && (!fields.hasOwnProperty(keyString) || fields[keyString] !== 1)) || (useNegativeFields && fields.hasOwnProperty(keyString) && fields[keyString] === -1)) { + return keyInfo; + } + + // We need to emit this key + if (keyInfo.hasOwnProperty(keyString) && keyInfo[keyString].hasOwnProperty(type)) { + keyInfo[keyString][type].perDoc += 1; + } else { + keyInfo[keyString] = {}; + keyInfo[keyString][type] = { + docs : 1, + coverage : 0, + perDoc : 1 + }; + } + + return keyInfo; + }; + + /** + * @function + * @name map + * @private + */ + map = function () { + var key, keyInfo, count, type; + + // Get our keyInfo struct + keyInfo = getKeyInfo(this, '', {}, [], true); + + // Loop through keys, emitting info + for (key in keyInfo) { + if (keyInfo.hasOwnProperty(key)) { + count = 0; + for (type in keyInfo[key]) { + if (keyInfo[key].hasOwnProperty(type)) { + count += keyInfo[key][type].perDoc; + } + } + keyInfo[key].all = { + docs : 1, + perDoc : count + }; + emit(key, keyInfo[key]); + } + } + }; + + /** + * @function + * @name reduce + * @private + * @param {string} key The key that was emitted from our map function + * @param {array} values An array of values that was emitted from our map function + */ + reduce = function (key, values) { + var result = {}; + values.forEach(function (value) { + var type; + for (type in value) { + if (value.hasOwnProperty(type)) { + if (!result.hasOwnProperty(type)) { + result[type] = { docs : 0, coverage : 0, perDoc : 0 }; + } + result[type].docs += value[type].docs; + result[type].perDoc += value[type].perDoc; + } + } + }); + return result; + }; + + /** + * @function + * @name finalize + * @private + * @param {string} key The key that was emitted/returned from our map/reduce functions + * @param {object} value The object that was returned from our reduce function + */ + finalize = function (key, value) { + var type, result = { + wildcard : (key.search(/^\$|\.\$/gi) >= 0), + types : [], + results : [{ + type : 'all', + docs : value.all.docs, + coverage : (value.all.docs / statCount) * 100, + perDoc : value.all.perDoc / value.all.docs + }] + }; + for (type in value) { + if (value.hasOwnProperty(type) && type !== 'all') { + result.types.push(type); + result.results.push({ + type : type, + docs : value[type].docs, + coverage : (value[type].docs / statCount) * 100, + perDoc : value[type].perDoc / value[type].docs + }); + } + } + return result; + }; + + // Start to setup our options struct + if (typeof optionsOrOutString === 'object') { + options = optionsOrOutString; + } else if (typeof optionsOrOutString === 'string') { + options.out = optionsOrOutString; + } + + // The default value for out is 'inline' + if (!options.hasOwnProperty('out')) { + options.out = { inline : 1 }; + } + + // Was a valid wildcards option passed in? + if (options.hasOwnProperty('wildcards') && getType(options.wildcards) === 'array') { + wildcards = options.wildcards; + } + + // Was a valid arraysAreWildcards option passed in? + if (options.hasOwnProperty('arraysAreWildcards') && typeof options.arraysAreWildcards === 'boolean') { + arraysAreWildcards = options.arraysAreWildcards; + } + + // Was a valid fields option passed in? + if (options.hasOwnProperty('fields') && getType(options.fields) === 'object' && Object.keySet(options.fields).length > 0) { + fields = options.fields; + for (field in fields) { + if (fields.hasOwnProperty(field)) { + if (fields[field] === 1 || fields[field] === true) { + fields[field] = 1; + usePositiveFields = true; + } else { + fields[field] = -1; + } + } + } + if (!usePositiveFields) { + useNegativeFields = true; + } + } + + // Store the total number of documents to be used in the finalize function + statCount = this.stats().count; + if (options.hasOwnProperty('limit') && typeof options.limit === 'number' && options.limit > 0 && options.limit < statCount) { + statCount = options.limit; + } else if (options.hasOwnProperty('limit')) { + delete options.limit; + } + + // Make sure to override certain options + options.map = map; + options.reduce = reduce; + options.finalize = finalize; + options.mapreduce = this._shortName; + options.scope = { + getType : getType, + getNewKeyString : getNewKeyString, + getKeyInfo : getKeyInfo, + statCount : statCount, + wildcards : wildcards, + arraysAreWildcards : arraysAreWildcards, + fields : fields, + usePositiveFields : usePositiveFields, + useNegativeFields : useNegativeFields + }; + + // Execute and return + print('Processing ' + statCount + ' document(s)...'); + return this.mapReduce(map, reduce, options); + }; + +}()); +/*jslint devel: false, nomen: true, maxerr: 50, indent: 4 */ +/** + * MongoDB - wild.js + * + * Version: 1.0 + * Date: April 29, 2012 + * Project: http://skratchdot.github.com/mongodb-wild/ + * Source Code: https://github.com/skratchdot/mongodb-wild/ + * Issues: https://github.com/skratchdot/mongodb-wild/issues/ + * Dependencies: MongoDB v1.8+ + * + * Description: + * + * Adds a wildcard search to the shell. You can run the new + * wild() function on a collection, or on a query result. + * The search is performed by converting each document to json, + * and then running a regex that json. + * + * Usage: + * + * // Search entire users collection for Bob + * db.users.wild('Bob'); + * db.users.wild(/Bob/gi); + * db.users.find().wild('Bob'); + * + * // Search for exact values of 'Bob' + * db.users.wild(': "Bob"'); + * + * // Search for exact keys called 'Bob' + * db.users.wild('"Bob" :'); + * + * // Search for documents containing 'Bob', filtering by last name of 'Smith' + * db.users.wild('Bob', {'name.last' : 'Smith'}); + * db.users.find({'name.last' : 'Smith'}).wild('Bob'); + * + * Copyright (c) 2012 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + 'use strict'; + + /** + * @function + * @name wild + * @memberOf DBQuery + * @param {String|RegExp} regex The regular expression to filter the query by + */ + DBQuery.prototype.wild = function (regex) { + var doc, result = []; + + // Ensure we have a valid regex + if (typeof regex === 'string') { + regex = new RegExp(regex, 'gi'); + } + if (regex instanceof RegExp === false) { + regex = new RegExp(); + } + + // Build our result set. + while (this.hasNext()) { + doc = this.next(); + if (tojson(doc).search(regex) >= 0) { + result.push(doc); + } + } + + return result; + }; + + /** + * @function + * @name wild + * @memberOf DBCollection + * @param {String|RegExp} regex The regular expression to filter the query by + * @param {object} query This value will be passed through to the .find() function + * @param {object} fields This value will be passed through to the .find() function + * @param {number} limit This value will be passed through to the .find() function + * @param {number} skip This value will be passed through to the .find() function + * @param {number} batchSize This value will be passed through to the .find() function + * @param {object} options This value will be passed through to the .find() function + */ + DBCollection.prototype.wild = function (regex, query, fields, limit, skip, batchSize, options) { + return this.find(query, fields, limit, skip, batchSize, options).wild(regex); + }; + +}()); +/** + * MongoDB - mesh.idrange.js + * Version: 1.0 + * Date: September 25, 2013 + * Description: + * + * Search collections for documents with ids created between 2 datetimes. + * + * Example Usage: + * + * // method 1: search the users collection for users created on 3/20/2013 + * var query = mesh.idrange('3/20/2013', '3/21/2013'); + * db.users.find(query); + * + * // method 2: search the users collection for users created on 3/20/2013 + * db.users.idrange('3/20/2013', '3/21/2013'); + * + * // search the users collection for users with first name "Bob" created in March + * db.users.idrange('3/1/2013', '4/1/2013', {"name.first": "Bob"}); + * + * Copyright (c) 2013 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + 'use strict'; + var idrange, toMoment; + + /** + * @function + * @name idrange + * @private + * + * Convert input to a valid moment object + */ + toMoment = function (input) { + input = moment(input); + if (!input || !input.isValid || !input.isValid()) { + input = moment(); + } + return input; + }; + + /** + * @function + * @name idrange + * @private + */ + idrange = function (one, two, properties) { + var result = {_id:{}}, moments, prop; + + // create our moments + moments = [toMoment(one), toMoment(two)]; + + // put them in the right order + moments.sort(function (a, b) { + return a.diff(b); + }); + + // setup our result + if (typeof properties === 'object') { + for (prop in properties) { + if (properties.hasOwnProperty(prop)) { + result[prop] = properties[prop]; + } + } + } + + // add moments to our result, and return + result._id.$gte = mesh.tid(moments[0]); + result._id.$lt = mesh.tid(moments[1]); + return result; + }; + + /** + * @function + * @name idrange + * @memberOf DBCollection + */ + DBCollection.prototype.idrange = function (one, two, properties) { + return this.find(idrange(one, two, properties)); + }; + + // store idrange on the mesh object + mesh.idrange = idrange; +}()); + +/*global mesh */ + +// http://docs.mongodb.org/manual/reference/operator/ +mesh.ops = {}; + +mesh.ops._query = { + "addToSet" : "$addToSet", + "all" : "$all", + "and" : "$and", + "bit" : "$bit", + "box" : "$box", + "center" : "$center", + "centerSphere" : "$centerSphere", + "comment" : "$comment", + "each" : "$each", + "elemMatch" : "$elemMatch", + "exists" : "$exists", + "explain" : "$explain", + "gt" : "$gt", + "gte" : "$gte", + "hint" : "$hint", + "in" : "$in", + "inc" : "$inc", + "isolated" : "$isolated", + "lt" : "$lt", + "lte" : "$lte", + "max" : "$max", + "maxDistance" : "$maxDistance", + "maxScan" : "$maxScan", + "min" : "$min", + "mod" : "$mod", + "natural" : "$natural", + "ne" : "$ne", + "near" : "$near", + "nearSphere" : "$nearSphere", + "nin" : "$nin", + "nor" : "$nor", + "not" : "$not", + "or" : "$or", + "orderby" : "$orderby", + "polygon" : "$polygon", + "pop" : "$pop", + "$" : "$", + "pull" : "$pull", + "pullAll" : "$pullAll", + "push" : "$push", + "pushAll" : "$pushAll", + "query" : "$query", + "regex" : "$regex", + "rename" : "$rename", + "returnKey" : "$returnKey", + "set" : "$set", + "setOnInsert" : "$setOnInsert", + "showDiskLoc" : "$showDiskLoc", + "size" : "$size", + "snapshot" : "$snapshot", + "type" : "$type", + "uniqueDocs" : "$uniqueDocs", + "unset" : "$unset", + "where" : "$where", + "within" : "$within" +}; + +mesh.ops._projection = { + "elemMatch" : "$elemMatch", + "$" : "$", + "slice" : "$slice" +}; + +mesh.ops._aggregation = { + "add" : "$add", + "addToSet" : "$addToSet", + "and" : "$and", + "avg" : "$avg", + "cmp" : "$cmp", + "cond" : "$cond", + "dayOfMonth" : "$dayOfMonth", + "dayOfWeek" : "$dayOfWeek", + "dayOfYear" : "$dayOfYear", + "divide" : "$divide", + "eq" : "$eq", + "first" : "$first", + "group" : "$group", + "gt" : "$gt", + "gte" : "$gte", + "hour" : "$hour", + "ifNull" : "$ifNull", + "last" : "$last", + "limit" : "$limit", + "lt" : "$lt", + "lte" : "$lte", + "match" : "$match", + "max" : "$max", + "min" : "$min", + "minute" : "$minute", + "mod" : "$mod", + "month" : "$month", + "multiply" : "$multiply", + "ne" : "$ne", + "not" : "$not", + "or" : "$or", + "project" : "$project", + "push" : "$push", + "second" : "$second", + "skip" : "$skip", + "sort" : "$sort", + "strcasecmp" : "$strcasecmp", + "substr" : "$substr", + "subtract" : "$subtract", + "sum" : "$sum", + "toLower" : "$toLower", + "toUpper" : "$toUpper", + "unwind" : "$unwind", + "week" : "$week", + "year" : "$year" +}; + +// build out ops +["_query", "_projection", "_aggregation"].forEach(function (section) { + 'use strict'; + var key; + for (key in mesh.ops[section]) { + if (mesh.ops[section].hasOwnProperty(key)) { + mesh.ops[key] = mesh.ops[section][key]; + } + } +}); + +/** + * MongoDB - mesh.sizeinfo.js + * Version: 1.0 + * Date: September 25, 2013 + * Description: + * + * Get the size stats for the given query/collection. Reports count/sum/avg/max/min of all bson sizes. + * + * Example Usage: + * + * // method 1: get the size stats for all documents in the users collection with first name "Bob" + * db.users.sizeinfo({"first.name": "Bob"}); + * + * // method 2: get the size stats for all documents in the users collection with first name "Bob" + * db.users.find({"first.name": "Bob"}).sizeinfo(); + * + * Copyright (c) 2013 SKRATCHDOT.COM + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function () { + var sizeinfo; + + /** + * @function + * @name sizeinfo + * @private + */ + sizeinfo = function (cursor) { + var doc, size, count = 0, sum = 0, max, min; + while (cursor.hasNext()) { + doc = cursor.next(); + size = Object.bsonsize(doc); + count += 1; + sum += size; + if (typeof max !== 'number' || max < size) { + max = size; + } + if (typeof min !== 'number' || min > size) { + min = size; + } + } + return { + count: count, + sum: sum, + max: max, + min: min, + avg: count > 0 ? sum / count : 0 + }; + }; + + /** + * @function + * @name sizeinfo + * @memberOf DBCollection + */ + DBQuery.prototype.sizeinfo = function () { + return sizeinfo(this); + }; + + /** + * @function + * @name sizeinfo + * @memberOf DBCollection + */ + DBCollection.prototype.sizeinfo = function (query, fields, limit, skip, batchSize, options) { + return this.find(query, fields, limit, skip, batchSize, options).sizeinfo(); + }; + +}()); + +/*global _, DBCollection, print */ +/** + * Insert an array of objects into a collection. + * + * This will loop through the array, calling DBCollection.insert() on each object. + * + * Example usage: + * + * // insert 2 items into myCollection + * var myArray = [{_id:1,test:1}, {_id:2,test:"foo"}]; + * db.myCollection.insertArray(myArray); + * + * // transfer a few items from collection1 into collection2 + * db.collection2.insertArray(db.collection1.find().limit(10).toArray()); + * + * @function + * @name insertArray + * @memberOf DBCollection + * @param {array} arr - The array of objects to insert. + * @param {object} options - pass through to DBCollection.prototype.insert() + * @param {boolean} _allow_dot - pass through to DBCollection.prototype.insert() + * @throws {Exception} - when arr is not an Array. + */ +DBCollection.prototype.insertArray = function (arr, options, _allow_dot) { + 'use strict'; + var i, obj; + if (_.isArray(arr)) { + for (i = 0; i < arr.length; i++) { + obj = arr[i]; + if (_.isObject(obj) && !_.isFunction(obj)) { + this.insert(obj, options, _allow_dot); + } else { + print('Cannot insert a non-object, so skipping: ' + obj); + } + } + } else { + throw 'first argument is not an array!'; + } +}; + +/*global _ : true, JSON : true */ + +_.mixin({ + aggregate : function (list, numericKey, keys) { + 'use strict'; + + var i = 0, + item = {}, + returnArray = [], + dataOrder = [], + data = {}, + AggregateError; + + // declare our AggregateError class + AggregateError = function (msg) { + this.name = 'AggregateError'; + this.message = msg || 'An error occurred while trying to perform aggregation'; + }; + AggregateError.prototype = new Error(); + AggregateError.prototype.constructor = AggregateError; + + // _.deepPluck is required + if (!_ || !_.deepPluck) { + throw new AggregateError("_.deepPluck is required for _.aggregate() to work."); + } + + // JSON.stringify is required + if (!JSON || !JSON.stringify) { + throw new AggregateError("JSON.stringify() is required for _.aggregate() to work."); + } + + // keys can be a single key (string), or an array of keys. + // we always want to deal with arrays though + if (typeof keys === 'string') { + keys = [keys]; + } + + // make sure keys is an array + if (!_.isArray(keys)) { + keys = []; + } + + _.each(list, function (obj) { + // declare some variables + var groupedValues = [], aggregationKey = '', numericValue; + + // get all our groupedValues + for (i = 0; i < keys.length; i++) { + groupedValues[i] = _.deepPluck([obj], keys[i])[0]; + } + + // create a key for our aggregations + aggregationKey = JSON.stringify(groupedValues); + + // get our current numeric value + numericValue = parseInt(_.deepPluck([obj], numericKey)[0], 10) || 0; + + if (data.hasOwnProperty(aggregationKey)) { + // count + data[aggregationKey].count = data[aggregationKey].count + 1; + // sum + data[aggregationKey].sum = data[aggregationKey].sum + numericValue; + // max + if (numericValue > data[aggregationKey].max) { + data[aggregationKey].max = numericValue; + } + // min + if (numericValue < data[aggregationKey].min) { + data[aggregationKey].min = numericValue; + } + // avg is calculated when building our return array + } else { + dataOrder.push(aggregationKey); + data[aggregationKey] = { + count : 1, + sum : numericValue, + max : numericValue, + min : numericValue, + avg : numericValue, + group : groupedValues + }; + } + + }); + + for (i = 0; i < dataOrder.length; i++) { + item = data[dataOrder[i]]; + item.avg = item.sum / item.count; + returnArray.push(item); + } + + return returnArray; + } +}); +/*global _:true */ + +_.mixin({ + avg : function (obj, iterator, context) { + 'use strict'; + var sum = _.sum(obj, iterator, context), + size = _.size(obj); + return size ? sum / size : 0; + } +}); +/*global _:true */ + +_.mixin({ + deepExtend : function (obj) { + 'use strict'; + _.each(Array.prototype.slice.call(arguments, 1), function (source) { + var key; + if (_.isObject(obj) && _.isObject(source) && !_.isArray(obj) && !_.isArray(source)) { + for (key in source) { + if (source.hasOwnProperty(key)) { + if (obj.hasOwnProperty(key)) { + obj[key] = _.deepExtend(obj[key], source[key]); + } else { + obj[key] = source[key]; + } + } + } + } else { + obj = source; + } + }); + return obj; + } +}); + +/*global _:true */ + +_.mixin({ + deepPluck : (function () { + 'use strict'; + + // declare some variables + var defaultDelimiter = '.', deepPluck; + + // implement the deepPluck function + deepPluck = function (obj, key, delimiter) { + if (typeof delimiter !== 'string') { + delimiter = defaultDelimiter; + } + return _.map(obj, function (value) { + var arr, i; + if (typeof key === 'string') { + arr = key.split(delimiter); + for (i = 0; i < arr.length; i++) { + if (value && typeof value === 'object' && value.hasOwnProperty(arr[i])) { + value = value[arr[i]]; + } else { + return; + } + } + return value; + } + }); + }; + + // allow the default delimiter to be overridden + // you may want to do this if you actually use dots in your keys + deepPluck.setDelimiter = function (delimiter) { + defaultDelimiter = delimiter; + }; + + return deepPluck; + }()) +}); +/*global _:true */ + +_.mixin({ + keyToObject : (function () { + 'use strict'; + + // declare some variables + var defaultDelimiter = '.', keyToObject; + + keyToObject = function (key, value, delimiter) { + var obj = {}, arr = []; + if (typeof delimiter !== 'string') { + delimiter = defaultDelimiter; + } + if (typeof key === 'string') { + arr = key.split(delimiter); + key = arr[0]; + if (arr.length > 1) { + arr.shift(); + obj[key] = keyToObject(arr.join(delimiter), value, delimiter); + } else { + obj[key] = value; + } + } + return obj; + }; + + // allow the default delimiter to be overridden + keyToObject.setDelimiter = function (delimiter) { + defaultDelimiter = delimiter; + }; + + return keyToObject; + }()) +}); +/*global _:true */ + +_.mixin({ + stdev : function (obj, iterator, context) { + 'use strict'; + return Math.sqrt(_.variance(obj, iterator, context)); + } +}); +/*global _:true */ + +_.mixin({ + sum : function (obj, iterator, context) { + 'use strict'; + var result = 0; + if (!iterator && _.isEmpty(obj)) { + return 0; + } + _.each(obj, function (value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + result += computed; + }); + return result; + } +}); +/*global _:true */ + +_.mixin({ + variance : function (obj, iterator, context) { + 'use strict'; + var result = 0, size = _.size(obj), mean; + if (size === 0) { + return 0; + } + // set mean + mean = _.avg(obj, iterator, context); + _.each(obj, function (value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value, + diff = computed - mean; + result += diff * diff; + }); + return result / size; + } +}); +// Mix in non-conflicting functions to the Underscore namespace +_.mixin(_.str.exports()); + +// Output the current version number when starting the shell. +mesh.version(); diff --git a/tools/sql2mongo/sql2mongo.js b/tools/sql2mongo/sql2mongo.js new file mode 100644 index 0000000..c9a437e --- /dev/null +++ b/tools/sql2mongo/sql2mongo.js @@ -0,0 +1,352 @@ +var _ = require('underscore') +sqlKeywords = ['select', 'top', 'from', 'join', 'where', 'groupby', 'orderby', 'having']; // keep "top x" in mind +logicalOperators = ['!=', '<=', '>=', '<', '>', '=', '!in', 'in', 'like']; + +var hasTop, hasWhere, hasOrderBy, processed = [], whereValsWithSpaces, hasOr, filterFields, operators, sqlishFilter, filter; +parseOperatorsInArray = function(equation){ + var completeArr = [], tmpArr = []; + sqlKeywords.forEach(function (e, k) { // for each operator + if (completeArr.length === 0) { // if empty, split equation and do first load to completeArr. + tmpArr = equation.split(e); + spliceOperatorIntoTmpArr(tmpArr, e); // adds operator between every item in array + tmpArr = tmpArr.filter(function (item) { return item.length > 0; }); + tmpArr.forEach(function (e, k) { + + if (e.indexOf('where') > -1){ + buildWhere(e); + } + completeArr.push(e.replace(/\s/g, '')); + }); + } else { + for (var n = 0; n < completeArr.length; n++) { + if (completeArr[n].indexOf(e) > -1 && completeArr[n].length > 1) { + var idx = n; + tmpArr = completeArr[n].split(e); + spliceOperatorIntoTmpArr(tmpArr, e); + tmpArr = tmpArr.filter(function (item) { return item.length > 0; }); + completeArr.splice(idx, 1); // remove old text element + for (var x = 0; x < tmpArr.length ; x++) { + var newIdx = (idx + x); + completeArr.splice(newIdx, 0, tmpArr[x]); + } + } + } + } + }); + return completeArr; +}; + +spliceOperatorIntoTmpArr = function(tmpArr, e){ + var tmpLen = tmpArr.length + (tmpArr.length - 1); + for (var i = 1; i < tmpLen; i++) { + tmpArr.splice(i, 0, e); + i++; + } +}; + +buildWhere = function(e){ + + var originalWhere = hasOrderBy ? e.substring(e.indexOf('where'), e.indexOf(' order by')) : e.substring(e.indexOf('where'), e.length); + var splitWhere = originalWhere.split(' '), splitLength = splitWhere.length; + var isRightSide = false, isOperator = false, isKeyword = false, filterValsToPush = []; + + splitWhere.forEach(function(el, idx){ + + isKeyword = ((sqlKeywords.indexOf(el) > -1) || el === 'and' || el === 'or'); + isOperator = (logicalOperators.indexOf(el) > -1); // true if operator + + if (isKeyword){ + isRightSide = false; // false if sql keyword + } + + if (isOperator){ + operators.push(el); + isRightSide = true; + } + + if (!isOperator && !isKeyword){ + if (isRightSide){ + filterValsToPush.push(el); + } else { + filterFields.push(el); + } + } + + if ((el === 'and' || el === 'or' || idx === (splitLength - 1)) && filterValsToPush.length > 0){ + var preservedVal = filterValsToPush.join(' '); + whereValsWithSpaces.push(preservedVal); + filterValsToPush = []; + } + }); + + for (var i = 0; i < filterFields.length; i++){ + sqlishFilter.push(({ field: filterFields[i], operator: operators[i], value: whereValsWithSpaces[i] })); + } +}; + +getNext = function(arr, howMany){ + howMany = howMany ? howMany : 1; + if (arr.length > 0){ + + var lastIn = arr.splice(0, howMany); + processed.push(lastIn); + return lastIn; + } +}; + +getLimit = function(arr){ + var topN = arr[0].replace(/[^0-9.]/g, ''); + // remove top n from fields portion of arr + arr[0] = arr[0].replace(/\d+/g, ''); + return parseInt(topN); +}; + +getProjection = function(arr){ + var projection = {}, selectFields = _.first(getNext(arr)); + if (selectFields !== '*'){ + selectFields.replace(/\s/g, '').split(',').forEach(function(e, k){ + var show = 1; + if (e.substr(0,1) === '!'){ + show = 0; + e = e.substr(1,1000); + } + projection[e] = show; + }); + } + return projection; +}; + +processFilter = function(filterObj, filter){ + var field = filterObj['field']; + var operator = filterObj['operator']; + var val = !isNaN(filterObj['value']) ? parseFloat(filterObj['value']) : filterObj['value']; + + switch (operator){ + case '=': + filter[field] = val; + break; + case '!=': + filter[field] = { $ne: val }; + break; + case '>': + filter[field] = { $gt: val }; + break; + case '<': + filter[field] = { $lt: val }; + break; + case '>=': + filter[field] = { $gte: val }; + break; + case '<=': + filter[field] = { $lte: val }; + break; + case 'in': + filter[field] = { $in: val.split(',') }; + break; + case '!in': + filter[field] = { $nin: val.split(',') }; + break; + case 'like': + filter[field] = { $regex: '^' + val + '.*' }; + break; + case '!like': + filter[field] = { $not: (new RegExp('/' + val + '/')) }; + break; + } + return filter; +}; + +getSort = function(arr){ + var sort = {}, sortFields = getNext(arr)[0], field, order, val; + sortFields.split(',').forEach(function(e, k){ + if (e.substring(e.length - 4, e.length) === 'desc'){ + field = e.substring(0, e.length - 4); + val = -1; + } else if (e.substring(e.length - 3, e.length) === 'asc'){ + field = e.substring(0, e.length - 3); + val = 1; + } else { + field = e; + val = 1; + } + + sort[field] = val; + }); + return sort; +}; + +validateCollection = function(collection){ + return _.contains(collections,collection) ? collection : 'Invalid Collection.'; +}; + +// ######## Start of custom auto-complete code ######## +function interceptAutoComplete(prefix, global, parts){ + if (prefix.length === 0){ // space only + return ["')"]; + } + + var first = parts[0].toLowerCase(); + var expandToText = snippetMap[first]; + var lastChar = first.substring(first.length - 1, first.length); + var lastTwoChars = first.substring(first.length - 2, first.length); + + if (first === 'sel'){ + sqlQuery = "db.sql('select * from "; + return [sqlQuery]; + } else if (expandToText){ + return [expandToText]; + } else if (!queryHasCollection && isNaN(lastChar)) { + return printCollections(first); + } else if (!queryHasCollection) { + return selectCollection(lastTwoChars, lastChar); + } else if (queryHasCollection && isNaN(lastChar)) { + return printFields(first); + } else { + return selectField(lastTwoChars, lastChar) + } +} + +function printMatches(isField){ + if (matches.length > 0){ + print('\n'); + matches.forEach(function(m, i){ + var str = i + ': ' + m + print(colorize(str, 'green', true, false)); + }); + } else { + resetGlobalVars(); + return ['']; + } +} + +function printCollections(first){ + // No collection has been selected yet, and user isn't passing number for selection... + if (_.contains(collections, first)){ + selectedCollection = first; + sqlQuery += selectedCollection; + + return [selectedCollection]; + } + + matches = _.filter(collections, function(c){ + return c.toLowerCase().substring(0, (first.length)) === first; + }); + + printMatches(); +} + +function selectCollection(lastTwoChars, lastChar){ + // no collection is selected yet, but user is passing number for selection... + var num = !isNaN(lastTwoChars) ? lastTwoChars : lastChar; + selectedCollection = matches[num]; + queryHasCollection = true; + print('\n'); + generateFieldTable(selectedCollection); + + if (sqlQuery === ''){ + sqlQuery = "db.sql('select * from " + selectedCollection; + return [sqlQuery]; + } + + sqlQuery += selectedCollection; + return [selectedCollection]; +} + +function printFields(first){ + // collection has been selected and user is trying to select field based on initial string + var collection = collectionFields[selectedCollection]; + var filteredFields = _.filter(collection, function(c){ + return c.field.toLowerCase().substring(0, (first.length)) === first; + }); + matches = _.map(_.sortBy(filteredFields, 'field'), function(d, i) { + return d.field; + }); + + printMatches(); +} + +function selectField(lastTwoChars, lastChar){ + // collection has been selected, as well as field string, now user is passing number to select one... + var num = !isNaN(lastTwoChars) ? lastTwoChars : lastChar; + var field = matches[num]; + + return [field]; +} + +function showCollections(){ + return db.getCollectionNames(); +} + +function resetGlobalVars (){ + queryHasCollection = false; + sqlQuery = ''; + matches = null; + selectedCollection = ''; +} + +function generateFieldTable(collection){ + var table = new AsciiTable(collection); + table.setHeading('#', 'Field', 'Types'); + + var fields = collectionFields[collection]; + _.map(_.sortBy(fields, 'field'), function(d, i) { + return table.addRow(i, d.field, d.types) + }); + return print(colorize(table, 'cyan', true, false)); +} +module.exports = { + parseSQL : function(sql){ + sql = sql.replace(/NOT LIKE/g,'!like').toLowerCase() + whereValsWithSpaces = [], filterFields = [], operators = [], sqlishFilter = [], filter = {}; + hasTop = (sql.indexOf(' top ') > -1), hasWhere = (sql.indexOf('where') > -1), hasOrderBy = (sql.indexOf('order by') > -1), hasOr = (sql.indexOf(' or ') > -1); + var limit, join, sort; + var arr = parseOperatorsInArray(sql); + + +// getNext(arr); // remove Select + + if (hasTop){ + getNext(arr); // remove top + limit = getLimit(arr); + } + console.log(sql) + console.log(arr) + var projection = getProjection(arr); + + getNext(arr); // remove From + + + if (hasWhere){ + var orObj = {}, orArr = []; + sqlishFilter.forEach(function(f, fk){ + if (hasOr){ + orArr.push(processFilter(f, {})); + } else { + processFilter(f, filter); + } + }); + + if (hasOr){ + filter = { $or: orArr }; + } + + getNext(arr, 2); // remove where and clause, since its handled earlier + } + + if (hasOrderBy){ + getNext(arr); // remove order by + sort = getSort(arr); + } + + + var ret = { + projection: projection, + filter: filter, + sort: sort || {}, + limit: limit || 20 + }; + + console.log('Converted Command: ' + 'db.' + ret.collection + '.find(' + JSON.stringify(ret.filter) + ', ' + JSON.stringify(ret.projection) + ').sort(' + JSON.stringify(ret.sort) + ').limit(' + ret.limit + ')'); + return ret; + } +} \ No newline at end of file diff --git a/tools/translateDefinitionFile.js b/tools/translateDefinitionFile.js new file mode 100644 index 0000000..8fc8ed4 --- /dev/null +++ b/tools/translateDefinitionFile.js @@ -0,0 +1,84 @@ +console.log('This translation tool uses Yandex.') +if(!process.argv[2]||!process.argv[3]||!process.argv[4]){ + console.log('You must input arguments.') + console.log('# node translateLanguageFile.js ') + console.log('Example:') + console.log('# node translateLanguageFile.js en_US en ar') + return +} +var defDir='../definitions/' +var fs=require('fs'); +var https = require('https'); +var jsonfile=require('jsonfile'); +var source=require(defDir+process.argv[2]+'.json') +var list = Object.keys(source) +console.log(list.length) +var extra = '' +var current = 1 +var currentItem = list[0] +var chosenFile = defDir+process.argv[4]+'.json' +try{ + newList=require(chosenFile) +}catch(err){ + console.log(chosenFile) + var newList={} +} +var newListAlphabetical={} +var goNext=function(){ + ++current + currentItem = list[current] + if(list.length===current){ + console.log('complete checking.. please wait') + Object.keys(newList).sort().forEach(function(y,t){ + newListAlphabetical[y]=newList[y] + }) + jsonfile.writeFile(chosenFile,newListAlphabetical,{spaces: 2},function(){ + console.log('complete writing') + }) + }else{ + next(currentItem) + } +} +var next=function(v){ + if(v===undefined){return false} + //trnsl.1.1.20170718T033617Z.a9bbd3b739ca59df.7f89b7474ec69812afd0014b5e338328ebf3fc39 + if(newList[v]&&newList[v]!==source[v]){ + goNext() + return + } + if(/<[a-z][\s\S]*>/i.test(source[v])===true){ + extra+='&format=html' + } + var url = 'https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20160311T042953Z.341f2f63f38bdac6.c7e5c01fff7f57160141021ca61b60e36ff4d379'+extra+'&lang='+process.argv[3]+'-'+process.argv[4]+'&text='+source[v] + https.request(url, function(data) { + data.setEncoding('utf8'); + var chunks=''; + data.on('data', (chunk) => { + chunks+=chunk; + }); + data.on('end', () => { + try{ + chunks=JSON.parse(chunks) + if(chunks.html){ + if(chunks.html[0]){ + var translation=chunks.html[0] + }else{ + var translation=chunks.html + } + + }else{ + var translation=chunks.text[0] + } + }catch(err){ + var translation=source[v] + } + newList[v]=translation; + console.log(current+'/'+list.length+','+v+' ---> '+translation) + goNext() + }); + }).on('error', function(e) { + console.log('ERROR : 500 '+v) + res.sendStatus(500); + }).end(); +} +next(currentItem) \ No newline at end of file diff --git a/tools/translateLanguageFile.js b/tools/translateLanguageFile.js new file mode 100644 index 0000000..418de20 --- /dev/null +++ b/tools/translateLanguageFile.js @@ -0,0 +1,84 @@ +console.log('This translation tool uses Yandex.') +if(!process.argv[2]||!process.argv[3]||!process.argv[4]){ + console.log('You must input arguments.') + console.log('# node translateLanguageFile.js ') + console.log('Example:') + console.log('# node translateLanguageFile.js en_US en ar') + return +} +var langDir='../languages/' +var fs=require('fs'); +var https = require('https'); +var jsonfile=require('jsonfile'); +var source=require(langDir+process.argv[2]+'.json') +var list = Object.keys(source) +console.log(list.length) +var extra = '' +var current = 1 +var currentItem = list[0] +var chosenFile = langDir+process.argv[4]+'.json' +try{ + newList=require(chosenFile) +}catch(err){ + console.log(chosenFile) + var newList={} +} +var newListAlphabetical={} +var goNext=function(){ + ++current + currentItem = list[current] + if(list.length===current){ + console.log('complete checking.. please wait') + Object.keys(newList).sort().forEach(function(y,t){ + newListAlphabetical[y]=newList[y] + }) + jsonfile.writeFile(chosenFile,newListAlphabetical,{spaces: 2},function(){ + console.log('complete writing') + }) + }else{ + next(currentItem) + } +} +var next=function(v){ + if(v===undefined){return false} + //trnsl.1.1.20170718T033617Z.a9bbd3b739ca59df.7f89b7474ec69812afd0014b5e338328ebf3fc39 + if(newList[v]&&newList[v]!==source[v]){ + goNext() + return + } + if(/<[a-z][\s\S]*>/i.test(source[v])===true){ + extra+='&format=html' + } + var url = 'https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20160311T042953Z.341f2f63f38bdac6.c7e5c01fff7f57160141021ca61b60e36ff4d379'+extra+'&lang='+process.argv[3]+'-'+process.argv[4]+'&text='+source[v] + https.request(url, function(data) { + data.setEncoding('utf8'); + var chunks=''; + data.on('data', (chunk) => { + chunks+=chunk; + }); + data.on('end', () => { + try{ + chunks=JSON.parse(chunks) + if(chunks.html){ + if(chunks.html[0]){ + var translation=chunks.html[0] + }else{ + var translation=chunks.html + } + + }else{ + var translation=chunks.text[0] + } + }catch(err){ + var translation=source[v] + } + newList[v]=translation; + console.log(current+'/'+list.length+','+v+' ---> '+translation) + goNext() + }); + }).on('error', function(e) { + console.log('ERROR : 500 '+v) + res.sendStatus(500); + }).end(); +} +next(currentItem) \ No newline at end of file diff --git a/web/libs/.gitignore b/web/libs/.gitignore new file mode 100644 index 0000000..efd261b --- /dev/null +++ b/web/libs/.gitignore @@ -0,0 +1 @@ +demo \ No newline at end of file diff --git a/web/libs/audio/alert.mp3 b/web/libs/audio/alert.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..4936bba4dc55ac5860edced0438057f554125841 GIT binary patch literal 13744 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,.bootstrap-table .table:not(.table-condensed)>tbody>tr>th,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>td,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>th,.bootstrap-table .table:not(.table-condensed)>thead>tr>td{padding:8px}.bootstrap-table .table.table-no-bordered>tbody>tr>td,.bootstrap-table .table.table-no-bordered>thead>tr>th{border-right:2px solid transparent}.bootstrap-table .table.table-no-bordered>tbody>tr>td:last-child{border-right:none}.fixed-table-container{position:relative;clear:both;border:1px solid #ddd;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px}.fixed-table-container.table-no-bordered{border:1px solid transparent}.fixed-table-footer,.fixed-table-header{overflow:hidden}.fixed-table-footer{border-top:1px solid #ddd}.fixed-table-body{overflow-x:auto;overflow-y:auto;height:100%}.fixed-table-container table{width:100%}.fixed-table-container thead th{height:0;padding:0;margin:0;border-left:1px solid #ddd}.fixed-table-container thead th:focus{outline:transparent solid 0}.fixed-table-container thead th:first-child{border-left:none;border-top-left-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px}.fixed-table-container tbody td .th-inner,.fixed-table-container thead th .th-inner{padding:8px;line-height:24px;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fixed-table-container thead th .sortable{cursor:pointer;background-position:right;background-repeat:no-repeat;padding-right:30px}.fixed-table-container thead th .both{background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC')}.fixed-table-container thead th .asc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==)}.fixed-table-container thead th .desc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII=)}.fixed-table-container th.detail{width:30px}.fixed-table-container tbody td{border-left:1px solid #ddd}.fixed-table-container tbody tr:first-child td{border-top:none}.fixed-table-container tbody td:first-child{border-left:none}.fixed-table-container tbody .selected td{background-color:#f5f5f5}.fixed-table-container .bs-checkbox .th-inner{padding:8px 0}.fixed-table-container input[type=radio],.fixed-table-container input[type=checkbox]{margin:0 auto!important}.fixed-table-pagination .pagination-detail,.fixed-table-pagination div.pagination{margin-top:10px;margin-bottom:10px}.fixed-table-pagination div.pagination .pagination{margin:0}.fixed-table-pagination .pagination a{padding:6px 12px;line-height:1.428571429}.fixed-table-pagination .pagination-info{line-height:34px;margin-right:5px}.fixed-table-pagination .btn-group{position:relative;display:inline-block;vertical-align:middle}.fixed-table-pagination .dropup .dropdown-menu{margin-bottom:0}.fixed-table-pagination .page-list{display:inline-block}.fixed-table-toolbar .columns-left{margin-right:5px}.fixed-table-toolbar .columns-right{margin-left:5px}.fixed-table-toolbar .columns label{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429}.fixed-table-toolbar .bs-bars,.fixed-table-toolbar .columns,.fixed-table-toolbar .search{position:relative;margin-top:10px;margin-bottom:10px;line-height:34px}.fixed-table-pagination li.disabled a{pointer-events:none;cursor:default}.fixed-table-loading{display:none;position:absolute;top:42px;right:0;bottom:0;left:0;z-index:99;background-color:#fff;text-align:center}.fixed-table-body .card-view .title{font-weight:700;display:inline-block;min-width:30%;text-align:left!important}.table td,.table th{vertical-align:middle}.fixed-table-toolbar .dropdown-menu{text-align:left;max-height:300px;overflow:auto}.fixed-table-toolbar .btn-group>.btn-group{display:inline-block;margin-left:-1px!important}.fixed-table-toolbar .btn-group>.btn-group>.btn{border-radius:0}.fixed-table-toolbar .btn-group>.btn-group:first-child>.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.fixed-table-toolbar .btn-group>.btn-group:last-child>.btn{border-top-right-radius:4px;border-bottom-right-radius:4px}.bootstrap-table .table>thead>tr>th{vertical-align:bottom;border-bottom:1px solid #ddd}.bootstrap-table .table thead>tr>th{padding:0;margin:0}.bootstrap-table .fixed-table-footer tbody>tr>td{padding:0!important}.bootstrap-table .fixed-table-footer .table{border-bottom:none;border-radius:0;padding:0!important}.pull-right .dropdown-menu{right:0;left:auto}p.fixed-table-scroll-inner{width:100%;height:200px}div.fixed-table-scroll-outer{top:0;left:0;visibility:hidden;width:200px;height:150px;overflow:hidden} \ No newline at end of file diff --git a/web/libs/css/bootstrap-theme.css b/web/libs/css/bootstrap-theme.css new file mode 100644 index 0000000..31d8882 --- /dev/null +++ b/web/libs/css/bootstrap-theme.css @@ -0,0 +1,587 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +.btn-default, +.btn-primary, +.btn-success, +.btn-info, +.btn-warning, +.btn-danger { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); +} +.btn-default:active, +.btn-primary:active, +.btn-success:active, +.btn-info:active, +.btn-warning:active, +.btn-danger:active, +.btn-default.active, +.btn-primary.active, +.btn-success.active, +.btn-info.active, +.btn-warning.active, +.btn-danger.active { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-default.disabled, +.btn-primary.disabled, +.btn-success.disabled, +.btn-info.disabled, +.btn-warning.disabled, +.btn-danger.disabled, +.btn-default[disabled], +.btn-primary[disabled], +.btn-success[disabled], +.btn-info[disabled], +.btn-warning[disabled], +.btn-danger[disabled], +fieldset[disabled] .btn-default, +fieldset[disabled] .btn-primary, +fieldset[disabled] .btn-success, +fieldset[disabled] .btn-info, +fieldset[disabled] .btn-warning, +fieldset[disabled] .btn-danger { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-default .badge, +.btn-primary .badge, +.btn-success .badge, +.btn-info .badge, +.btn-warning .badge, +.btn-danger .badge { + text-shadow: none; +} +.btn:active, +.btn.active { + background-image: none; +} +.btn-default { + text-shadow: 0 1px 0 #fff; + background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); + background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #dbdbdb; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus { + background-color: #e0e0e0; + background-position: 0 -15px; +} +.btn-default:active, +.btn-default.active { + background-color: #e0e0e0; + border-color: #dbdbdb; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #e0e0e0; + background-image: none; +} +.btn-primary { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); + background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #245580; +} +.btn-primary:hover, +.btn-primary:focus { + background-color: #265a88; + background-position: 0 -15px; +} +.btn-primary:active, +.btn-primary.active { + background-color: #265a88; + border-color: #245580; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #265a88; + background-image: none; +} +.btn-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #3e8f3e; +} +.btn-success:hover, +.btn-success:focus { + background-color: #419641; + background-position: 0 -15px; +} +.btn-success:active, +.btn-success.active { + background-color: #419641; + border-color: #3e8f3e; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #419641; + background-image: none; +} +.btn-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #28a4c9; +} +.btn-info:hover, +.btn-info:focus { + background-color: #2aabd2; + background-position: 0 -15px; +} +.btn-info:active, +.btn-info.active { + background-color: #2aabd2; + border-color: #28a4c9; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #2aabd2; + background-image: none; +} +.btn-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #e38d13; +} +.btn-warning:hover, +.btn-warning:focus { + background-color: #eb9316; + background-position: 0 -15px; +} +.btn-warning:active, +.btn-warning.active { + background-color: #eb9316; + border-color: #e38d13; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #eb9316; + background-image: none; +} +.btn-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #b92c28; +} +.btn-danger:hover, +.btn-danger:focus { + background-color: #c12e2a; + background-position: 0 -15px; +} +.btn-danger:active, +.btn-danger.active { + background-color: #c12e2a; + border-color: #b92c28; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #c12e2a; + background-image: none; +} +.thumbnail, +.img-thumbnail { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #e8e8e8; + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + background-color: #2e6da4; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; +} +.navbar-default { + background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); + background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); + background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); +} +.navbar-brand, +.navbar-nav > li > a { + text-shadow: 0 1px 0 rgba(255, 255, 255, .25); +} +.navbar-inverse { + background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); + background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); + background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); +} +.navbar-inverse .navbar-brand, +.navbar-inverse .navbar-nav > li > a { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); +} +.navbar-static-top, +.navbar-fixed-top, +.navbar-fixed-bottom { + border-radius: 0; +} +@media (max-width: 767px) { + .navbar .navbar-nav .open .dropdown-menu > .active > a, + .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; + } +} +.alert { + text-shadow: 0 1px 0 rgba(255, 255, 255, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); +} +.alert-success { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); + background-repeat: repeat-x; + border-color: #b2dba1; +} +.alert-info { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); + background-repeat: repeat-x; + border-color: #9acfea; +} +.alert-warning { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); + background-repeat: repeat-x; + border-color: #f5e79e; +} +.alert-danger { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); + background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); + background-repeat: repeat-x; + border-color: #dca7a7; +} +.progress { + background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); + background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-striped { + background-image: -webkit-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-image: -o-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-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); +} +.list-group { + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + text-shadow: 0 -1px 0 #286090; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); + background-repeat: repeat-x; + border-color: #2b669a; +} +.list-group-item.active .badge, +.list-group-item.active:hover .badge, +.list-group-item.active:focus .badge { + text-shadow: none; +} +.panel { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: 0 1px 2px rgba(0, 0, 0, .05); +} +.panel-default > .panel-heading { + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.panel-primary > .panel-heading { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; +} +.panel-success > .panel-heading { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); + background-repeat: repeat-x; +} +.panel-info > .panel-heading { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); + background-repeat: repeat-x; +} +.panel-warning > .panel-heading { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); + background-repeat: repeat-x; +} +.panel-danger > .panel-heading { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); + background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); + background-repeat: repeat-x; +} +.well { + background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; + border-color: #dcdcdc; + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); +} +/*# sourceMappingURL=bootstrap-theme.css.map */ diff --git a/web/libs/css/bootstrap-theme.css.map b/web/libs/css/bootstrap-theme.css.map new file mode 100644 index 0000000..d876f60 --- /dev/null +++ b/web/libs/css/bootstrap-theme.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["bootstrap-theme.css","less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"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","file":"bootstrap-theme.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file diff --git a/web/libs/css/bootstrap-theme.min.css b/web/libs/css/bootstrap-theme.min.css new file mode 100644 index 0000000..5e39401 --- /dev/null +++ b/web/libs/css/bootstrap-theme.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-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-image:-o-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-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)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} +/*# sourceMappingURL=bootstrap-theme.min.css.map */ \ No newline at end of file diff --git a/web/libs/css/bootstrap-theme.min.css.map b/web/libs/css/bootstrap-theme.min.css.map new file mode 100644 index 0000000..94813e9 --- /dev/null +++ b/web/libs/css/bootstrap-theme.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file diff --git a/web/libs/css/bootstrap.css b/web/libs/css/bootstrap.css new file mode 100644 index 0000000..6167622 --- /dev/null +++ b/web/libs/css/bootstrap.css @@ -0,0 +1,6757 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background-color: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + margin: .67em 0; + font-size: 2em; +} +mark { + color: #000; + background: #ff0; +} +small { + font-size: 80%; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -.5em; +} +sub { + bottom: -.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + height: 0; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + margin: 0; + font: inherit; + color: inherit; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} +legend { + padding: 0; + border: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-spacing: 0; + border-collapse: collapse; +} +td, +th { + padding: 0; +} +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ +@media print { + *, + *:before, + *:after { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + .navbar { + display: none; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\002a"; +} +.glyphicon-plus:before { + content: "\002b"; +} +.glyphicon-euro:before, +.glyphicon-eur:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +.glyphicon-cd:before { + content: "\e201"; +} +.glyphicon-save-file:before { + content: "\e202"; +} +.glyphicon-open-file:before { + content: "\e203"; +} +.glyphicon-level-up:before { + content: "\e204"; +} +.glyphicon-copy:before { + content: "\e205"; +} +.glyphicon-paste:before { + content: "\e206"; +} +.glyphicon-alert:before { + content: "\e209"; +} +.glyphicon-equalizer:before { + content: "\e210"; +} +.glyphicon-king:before { + content: "\e211"; +} +.glyphicon-queen:before { + content: "\e212"; +} +.glyphicon-pawn:before { + content: "\e213"; +} +.glyphicon-bishop:before { + content: "\e214"; +} +.glyphicon-knight:before { + content: "\e215"; +} +.glyphicon-baby-formula:before { + content: "\e216"; +} +.glyphicon-tent:before { + content: "\26fa"; +} +.glyphicon-blackboard:before { + content: "\e218"; +} +.glyphicon-bed:before { + content: "\e219"; +} +.glyphicon-apple:before { + content: "\f8ff"; +} +.glyphicon-erase:before { + content: "\e221"; +} +.glyphicon-hourglass:before { + content: "\231b"; +} +.glyphicon-lamp:before { + content: "\e223"; +} +.glyphicon-duplicate:before { + content: "\e224"; +} +.glyphicon-piggy-bank:before { + content: "\e225"; +} +.glyphicon-scissors:before { + content: "\e226"; +} +.glyphicon-bitcoin:before { + content: "\e227"; +} +.glyphicon-btc:before { + content: "\e227"; +} +.glyphicon-xbt:before { + content: "\e227"; +} +.glyphicon-yen:before { + content: "\00a5"; +} +.glyphicon-jpy:before { + content: "\00a5"; +} +.glyphicon-ruble:before { + content: "\20bd"; +} +.glyphicon-rub:before { + content: "\20bd"; +} +.glyphicon-scale:before { + content: "\e230"; +} +.glyphicon-ice-lolly:before { + content: "\e231"; +} +.glyphicon-ice-lolly-tasted:before { + content: "\e232"; +} +.glyphicon-education:before { + content: "\e233"; +} +.glyphicon-option-horizontal:before { + content: "\e234"; +} +.glyphicon-option-vertical:before { + content: "\e235"; +} +.glyphicon-menu-hamburger:before { + content: "\e236"; +} +.glyphicon-modal-window:before { + content: "\e237"; +} +.glyphicon-oil:before { + content: "\e238"; +} +.glyphicon-grain:before { + content: "\e239"; +} +.glyphicon-sunglasses:before { + content: "\e240"; +} +.glyphicon-text-size:before { + content: "\e241"; +} +.glyphicon-text-color:before { + content: "\e242"; +} +.glyphicon-text-background:before { + content: "\e243"; +} +.glyphicon-object-align-top:before { + content: "\e244"; +} +.glyphicon-object-align-bottom:before { + content: "\e245"; +} +.glyphicon-object-align-horizontal:before { + content: "\e246"; +} +.glyphicon-object-align-left:before { + content: "\e247"; +} +.glyphicon-object-align-vertical:before { + content: "\e248"; +} +.glyphicon-object-align-right:before { + content: "\e249"; +} +.glyphicon-triangle-right:before { + content: "\e250"; +} +.glyphicon-triangle-left:before { + content: "\e251"; +} +.glyphicon-triangle-bottom:before { + content: "\e252"; +} +.glyphicon-triangle-top:before { + content: "\e253"; +} +.glyphicon-console:before { + content: "\e254"; +} +.glyphicon-superscript:before { + content: "\e255"; +} +.glyphicon-subscript:before { + content: "\e256"; +} +.glyphicon-menu-left:before { + content: "\e257"; +} +.glyphicon-menu-right:before { + content: "\e258"; +} +.glyphicon-menu-down:before { + content: "\e259"; +} +.glyphicon-menu-up:before { + content: "\e260"; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #337ab7; + text-decoration: none; +} +a:hover, +a:focus { + color: #23527c; + text-decoration: underline; +} +a:focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + display: inline-block; + max-width: 100%; + height: auto; + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +[role="button"] { + cursor: pointer; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #777; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 30px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 14px; +} +h6, +.h6 { + font-size: 12px; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 300; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} +small, +.small { + font-size: 85%; +} +mark, +.mark { + padding: .2em; + background-color: #fcf8e3; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-nowrap { + white-space: nowrap; +} +.text-lowercase { + text-transform: lowercase; +} +.text-uppercase { + text-transform: uppercase; +} +.text-capitalize { + text-transform: capitalize; +} +.text-muted { + color: #777; +} +.text-primary { + color: #337ab7; +} +a.text-primary:hover, +a.text-primary:focus { + color: #286090; +} +.text-success { + color: #3c763d; +} +a.text-success:hover, +a.text-success:focus { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover, +a.text-info:focus { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover, +a.text-warning:focus { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover, +a.text-danger:focus { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #337ab7; +} +a.bg-primary:hover, +a.bg-primary:focus { + background-color: #286090; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover, +a.bg-success:focus { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover, +a.bg-info:focus { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover, +a.bg-warning:focus { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover, +a.bg-danger:focus { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + margin-left: -5px; + list-style: none; +} +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #777; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + text-align: right; + border-right: 5px solid #eee; + border-left: 0; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.42857143; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + -webkit-box-shadow: none; + box-shadow: none; +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +.row { + margin-right: -15px; + margin-left: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0; +} +@media (min-width: 768px) { + .col-sm-1, .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-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0; + } +} +@media (min-width: 992px) { + .col-md-1, .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-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0; + } +} +@media (min-width: 1200px) { + .col-lg-1, .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-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0; + } +} +table { + background-color: transparent; +} +caption { + padding-top: 8px; + padding-bottom: 8px; + color: #777; + text-align: left; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + display: table-column; + float: none; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + display: table-cell; + float: none; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +.table-responsive { + min-height: .01%; + overflow-x: auto; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857143; + color: #555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); +} +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999; +} +.form-control::-webkit-input-placeholder { + color: #999; +} +.form-control::-ms-expand { + background-color: transparent; + border: 0; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + background-color: #eee; + opacity: 1; +} +.form-control[disabled], +fieldset[disabled] .form-control { + cursor: not-allowed; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"].form-control, + input[type="time"].form-control, + input[type="datetime-local"].form-control, + input[type="month"].form-control { + line-height: 34px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm, + .input-group-sm input[type="date"], + .input-group-sm input[type="time"], + .input-group-sm input[type="datetime-local"], + .input-group-sm input[type="month"] { + line-height: 30px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg, + .input-group-lg input[type="date"], + .input-group-lg input[type="time"], + .input-group-lg input[type="datetime-local"], + .input-group-lg input[type="month"] { + line-height: 46px; + } +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: 4px \9; + margin-left: -20px; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + min-height: 34px; + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-right: 0; + padding-left: 0; +} +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.form-group-sm select.form-control { + height: 30px; + line-height: 30px; +} +.form-group-sm textarea.form-control, +.form-group-sm select[multiple].form-control { + height: auto; +} +.form-group-sm .form-control-static { + height: 30px; + min-height: 32px; + padding: 6px 10px; + font-size: 12px; + line-height: 1.5; +} +.input-lg { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-lg { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.form-group-lg select.form-control { + height: 46px; + line-height: 46px; +} +.form-group-lg textarea.form-control, +.form-group-lg select[multiple].form-control { + height: auto; +} +.form-group-lg .form-control-static { + height: 46px; + min-height: 38px; + padding: 11px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; + pointer-events: none; +} +.input-lg + .form-control-feedback, +.input-group-lg + .form-control-feedback, +.form-group-lg .form-control + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} +.input-sm + .form-control-feedback, +.input-group-sm + .form-control-feedback, +.form-group-sm .form-control + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; +} +.has-error .form-control-feedback { + color: #a94442; +} +.has-feedback label ~ .form-control-feedback { + top: 25px; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + padding-top: 7px; + margin-bottom: 0; + text-align: right; + } +} +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 11px; + font-size: 18px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + font-size: 12px; + } +} +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #333; + text-decoration: none; +} +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; + opacity: .65; +} +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:focus, +.btn-default.focus { + color: #333; + background-color: #e6e6e6; + border-color: #8c8c8c; +} +.btn-default:hover { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active:hover, +.btn-default.active:hover, +.open > .dropdown-toggle.btn-default:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.open > .dropdown-toggle.btn-default:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn-default.focus { + color: #333; + background-color: #d4d4d4; + border-color: #8c8c8c; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus { + background-color: #fff; + border-color: #ccc; +} +.btn-default .badge { + color: #fff; + background-color: #333; +} +.btn-primary { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary:focus, +.btn-primary.focus { + color: #fff; + background-color: #286090; + border-color: #122b40; +} +.btn-primary:hover { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active:hover, +.btn-primary.active:hover, +.open > .dropdown-toggle.btn-primary:hover, +.btn-primary:active:focus, +.btn-primary.active:focus, +.open > .dropdown-toggle.btn-primary:focus, +.btn-primary:active.focus, +.btn-primary.active.focus, +.open > .dropdown-toggle.btn-primary.focus { + color: #fff; + background-color: #204d74; + border-color: #122b40; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus { + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary .badge { + color: #337ab7; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:focus, +.btn-success.focus { + color: #fff; + background-color: #449d44; + border-color: #255625; +} +.btn-success:hover { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active:hover, +.btn-success.active:hover, +.open > .dropdown-toggle.btn-success:hover, +.btn-success:active:focus, +.btn-success.active:focus, +.open > .dropdown-toggle.btn-success:focus, +.btn-success:active.focus, +.btn-success.active.focus, +.open > .dropdown-toggle.btn-success.focus { + color: #fff; + background-color: #398439; + border-color: #255625; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:focus, +.btn-info.focus { + color: #fff; + background-color: #31b0d5; + border-color: #1b6d85; +} +.btn-info:hover { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active:hover, +.btn-info.active:hover, +.open > .dropdown-toggle.btn-info:hover, +.btn-info:active:focus, +.btn-info.active:focus, +.open > .dropdown-toggle.btn-info:focus, +.btn-info:active.focus, +.btn-info.active.focus, +.open > .dropdown-toggle.btn-info.focus { + color: #fff; + background-color: #269abc; + border-color: #1b6d85; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:focus, +.btn-warning.focus { + color: #fff; + background-color: #ec971f; + border-color: #985f0d; +} +.btn-warning:hover { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active:hover, +.btn-warning.active:hover, +.open > .dropdown-toggle.btn-warning:hover, +.btn-warning:active:focus, +.btn-warning.active:focus, +.open > .dropdown-toggle.btn-warning:focus, +.btn-warning:active.focus, +.btn-warning.active.focus, +.open > .dropdown-toggle.btn-warning.focus { + color: #fff; + background-color: #d58512; + border-color: #985f0d; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:focus, +.btn-danger.focus { + color: #fff; + background-color: #c9302c; + border-color: #761c19; +} +.btn-danger:hover { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active:hover, +.btn-danger.active:hover, +.open > .dropdown-toggle.btn-danger:hover, +.btn-danger:active:focus, +.btn-danger.active:focus, +.open > .dropdown-toggle.btn-danger:focus, +.btn-danger:active.focus, +.btn-danger.active.focus, +.open > .dropdown-toggle.btn-danger.focus { + color: #fff; + background-color: #ac2925; + border-color: #761c19; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #337ab7; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link.active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-timing-function: ease; + -o-transition-timing-function: ease; + transition-timing-function: ease; + -webkit-transition-duration: .35s; + -o-transition-duration: .35s; + transition-duration: .35s; + -webkit-transition-property: height, visibility; + -o-transition-property: height, visibility; + transition-property: height, visibility; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid \9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + text-align: left; + list-style: none; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + background-color: #337ab7; + outline: 0; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #777; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + right: 0; + left: auto; +} +.dropdown-menu-left { + right: auto; + left: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #777; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + content: ""; + border-top: 0; + border-bottom: 4px dashed; + border-bottom: 4px solid \9; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } + .navbar-right .dropdown-menu-left { + right: auto; + left: 0; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn, +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + display: table-cell; + float: none; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group .form-control:focus { + z-index: 3; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + z-index: 2; + margin-left: -1px; +} +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li.disabled > a { + color: #777; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #777; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eee; + border-color: #337ab7; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eee #eee #ddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #fff; + background-color: #337ab7; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + height: 50px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +.navbar-brand > img { + display: block; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -15px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777; +} +.navbar-default .navbar-nav > li > a { + color: #777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #ddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #888; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555; + background-color: #e7e7e7; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777; +} +.navbar-default .navbar-link:hover { + color: #333; +} +.navbar-default .btn-link { + color: #777; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #333; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #ccc; +} +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #9d9d9d; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + color: #fff; + background-color: #080808; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #9d9d9d; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #9d9d9d; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.navbar-inverse .btn-link { + color: #9d9d9d; +} +.navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link:focus { + color: #fff; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #444; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + padding: 0 5px; + color: #ccc; + content: "/\00a0"; +} +.breadcrumb > .active { + color: #777; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.42857143; + color: #337ab7; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + z-index: 2; + color: #23527c; + background-color: #eee; + border-color: #ddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 3; + color: #fff; + cursor: default; + background-color: #337ab7; + border-color: #337ab7; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #777; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eee; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #777; + cursor: not-allowed; + background-color: #fff; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #777; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #5e5e5e; +} +.label-primary { + background-color: #337ab7; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #286090; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: middle; + background-color: #777; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge, +.btn-group-xs > .btn .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #337ab7; + background-color: #fff; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding-top: 30px; + padding-bottom: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #eee; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; +} +.jumbotron > hr { + border-top-color: #d5d5d5; +} +.container .jumbotron, +.container-fluid .jumbotron { + padding-right: 15px; + padding-left: 15px; + border-radius: 6px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: border .2s ease-in-out; + -o-transition: border .2s ease-in-out; + transition: border .2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-right: auto; + margin-left: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #337ab7; +} +.thumbnail .caption { + padding: 9px; + color: #333; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #337ab7; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + -webkit-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-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-image: -o-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-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); + -webkit-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #5cb85c; +} +.progress-striped .progress-bar-success { + background-image: -webkit-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-image: -o-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-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); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-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-image: -o-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-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); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-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-image: -o-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-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); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-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-image: -o-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-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); +} +.media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media-body { + width: 10000px; +} +.media-object { + display: block; +} +.media-object.img-thumbnail { + max-width: none; +} +.media-right, +.media > .pull-right { + padding-left: 10px; +} +.media-left, +.media > .pull-left { + padding-right: 10px; +} +.media-left, +.media-right, +.media-body { + display: table-cell; + vertical-align: top; +} +.media-middle { + vertical-align: middle; +} +.media-bottom { + vertical-align: bottom; +} +.media-heading { + margin-top: 0; + margin-bottom: 5px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + padding-left: 0; + margin-bottom: 20px; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +a.list-group-item, +button.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading, +button.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, +button.list-group-item:hover, +a.list-group-item:focus, +button.list-group-item:focus { + color: #555; + text-decoration: none; + background-color: #f5f5f5; +} +button.list-group-item { + width: 100%; + text-align: left; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + color: #777; + cursor: not-allowed; + background-color: #eee; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #777; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #c7ddef; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success, +button.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading, +button.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +button.list-group-item-success:hover, +a.list-group-item-success:focus, +button.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +button.list-group-item-success.active, +a.list-group-item-success.active:hover, +button.list-group-item-success.active:hover, +a.list-group-item-success.active:focus, +button.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info, +button.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading, +button.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +button.list-group-item-info:hover, +a.list-group-item-info:focus, +button.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +button.list-group-item-info.active, +a.list-group-item-info.active:hover, +button.list-group-item-info.active:hover, +a.list-group-item-info.active:focus, +button.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning, +button.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading, +button.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +button.list-group-item-warning:hover, +a.list-group-item-warning:focus, +button.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +button.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +button.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus, +button.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger, +button.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading, +button.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +button.list-group-item-danger:hover, +a.list-group-item-danger:focus, +button.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +button.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +button.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus, +button.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a, +.panel-title > small, +.panel-title > .small, +.panel-title > small > a, +.panel-title > .small > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group, +.panel > .panel-collapse > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item, +.panel > .panel-collapse > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child, +.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child, +.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table caption, +.panel > .table-responsive > .table caption, +.panel > .panel-collapse > .table caption { + padding-right: 15px; + padding-left: 15px; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive, +.panel > .table + .panel-body, +.panel > .table-responsive + .panel-body { + border-top: 1px solid #ddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + margin-bottom: 0; + border: 0; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body, +.panel-group .panel-heading + .panel-collapse > .list-group { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default > .panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ddd; +} +.panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #337ab7; +} +.panel-primary > .panel-heading { + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #337ab7; +} +.panel-primary > .panel-heading .badge { + color: #337ab7; + background-color: #fff; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #337ab7; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-heading .badge { + color: #dff0d8; + background-color: #3c763d; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-heading .badge { + color: #d9edf7; + background-color: #31708f; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #bce8f1; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-heading .badge { + color: #fcf8e3; + background-color: #8a6d3b; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-heading .badge { + color: #f2dede; + background-color: #a94442; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ebccd1; +} +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} +.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.embed-responsive-4by3 { + padding-bottom: 75%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, .15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: .2; +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + filter: alpha(opacity=50); + opacity: .5; +} +button.close { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + filter: alpha(opacity=0); + opacity: 0; +} +.modal-backdrop.in { + filter: alpha(opacity=50); + opacity: .5; +} +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 15px; +} +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; + font-style: normal; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + filter: alpha(opacity=0); + opacity: 0; + + line-break: auto; +} +.tooltip.in { + filter: alpha(opacity=90); + opacity: .9; +} +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-left .tooltip-arrow { + right: 5px; + bottom: 0; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-right .tooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + + line-break: auto; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + content: ""; + border-width: 10px; +} +.popover.top > .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, .25); + border-bottom-width: 0; +} +.popover.top > .arrow:after { + bottom: 1px; + margin-left: -10px; + content: " "; + border-top-color: #fff; + border-bottom-width: 0; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, .25); + border-left-width: 0; +} +.popover.right > .arrow:after { + bottom: -10px; + left: 1px; + content: " "; + border-right-color: #fff; + border-left-width: 0; +} +.popover.bottom > .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, .25); +} +.popover.bottom > .arrow:after { + top: 1px; + margin-left: -10px; + content: " "; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, .25); +} +.popover.left > .arrow:after { + right: 1px; + bottom: -10px; + content: " "; + border-right-width: 0; + border-left-color: #fff; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +@media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .item { + -webkit-transition: -webkit-transform .6s ease-in-out; + -o-transition: -o-transform .6s ease-in-out; + transition: transform .6s ease-in-out; + + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + perspective: 1000px; + } + .carousel-inner > .item.next, + .carousel-inner > .item.active.right { + left: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + .carousel-inner > .item.prev, + .carousel-inner > .item.active.left { + left: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + .carousel-inner > .item.next.left, + .carousel-inner > .item.prev.right, + .carousel-inner > .item.active { + left: 0; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + background-color: rgba(0, 0, 0, 0); + filter: alpha(opacity=50); + opacity: .5; +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control:hover, +.carousel-control:focus { + color: #fff; + text-decoration: none; + filter: alpha(opacity=90); + outline: 0; + opacity: .9; +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + margin-top: -10px; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + font-family: serif; + line-height: 1; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; +} +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -10px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -10px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -10px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-header:before, +.modal-header:after, +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-header:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +/*# sourceMappingURL=bootstrap.css.map */ diff --git a/web/libs/css/bootstrap.css.map b/web/libs/css/bootstrap.css.map new file mode 100644 index 0000000..f010c82 --- /dev/null +++ b/web/libs/css/bootstrap.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"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AW,iBAAA;CHsR9C;AGrRmC;EAAW,iBAAA;CHwR9C;AGvRmC;EAAW,iBAAA;CH0R9C;AGzRmC;EAAW,iBAAA;CH4R9C;AG3RmC;EAAW,iBAAA;CH8R9C;AG7RmC;EAAW,iBAAA;CHgS9C;AG/RmC;EAAW,iBAAA;CHkS9C;AGjSmC;EAAW,iBAAA;CHoS9C;AGnSmC;EAAW,iBAAA;CHsS9C;AGrSmC;EAAW,iBAAA;CHwS9C;AGvSmC;EAAW,iBAAA;CH0S9C;AGzSmC;EAAW,iBAAA;CH4S9C;AG3SmC;EAAW,iBAAA;CH8S9C;AG7SmC;EAAW,iBAAA;CHgT9C;AG/SmC;EAAW,iBAAA;CHkT9C;AGjTmC;EAAW,iBAAA;CHoT9C;AGnTmC;EAAW,iBAAA;CHsT9C;AGrTmC;EAAW,iBAAA;CHwT9C;AGvTmC;EAAW,iBAAA;CH0T9C;AGzTmC;EAAW,iBAAA;CH4T9C;AG3TmC;EAAW,iBAAA;CH8T9C;AG7TmC;EAAW,iBAAA;CHgU9C;AG/TmC;EAAW,iBAAA;CHkU9C;AGjUmC;EAAW,iBAAA;CHoU9C;AGnUmC;EAAW,iBAAA;CHsU9C;AGrUmC;EAAW,iBAAA;CHwU9C;AGvUmC;EAAW,iBAAA;CH0U9C;AGzUmC;EAAW,iBAAA;CH4U9C;AG3UmC;EAAW,iBAAA;CH8U9C;AG7UmC;EAAW,iBAAA;CHgV9C;AG/UmC;EAAW,iBAAA;CHkV9C;AGjVmC;EAAW,iBAAA;CHoV9C;AGnVmC;EAAW,iBAAA;CHsV9C;AGrVmC;EAAW,iBAAA;CHwV9C;AGvVmC;EAAW,iBAAA;CH0V9C;AGzVmC;EAAW,iBAAA;CH4V9C;AG3VmC;EAAW,iBAAA;CH8V9C;AG7VmC;EAAW,iBAAA;CHgW9C;AG/VmC;EAAW,iBAAA;CHkW9C;AGjWmC;EAAW,iBAAA;CHoW9C;AGnWmC;EAAW,iBAAA;CHsW9C;AGrWmC;EAAW,iBAAA;CHwW9C;AGvWmC;EAAW,iBAAA;CH0W9C;AGzWmC;EAAW,iBAAA;CH4W9C;AG3WmC;EAAW,iBAAA;CH8W9C;AG7WmC;EAAW,iBAAA;CHgX9C;AG/WmC;EAAW,iBAAA;CHkX9C;AGjXmC;EAAW,iBAAA;CHoX9C;AGnXmC;EAAW,iBAAA;CHsX9C;AGrXmC;EAAW,iBAAA;CHwX9C;AGvXmC;EAAW,iBAAA;CH0X9C;AGzXmC;EAAW,iBAAA;CH4X9C;AG3XmC;EAAW,iBAAA;CH8X9C;AG7XmC;EAAW,iBAAA;CHgY9C;AG/XmC;EAAW,iBAAA;CHkY9C;AGjYmC;EAAW,iBAAA;CHoY9C;AGnYmC;EAAW,iBAAA;CHsY9C;AGrYmC;EAAW,iBAAA;CHwY9C;AGvYmC;EAAW,iBAAA;CH0Y9C;AGzYmC;EAAW,iBAAA;CH4Y9C;AG3YmC;EAAW,iBAAA;CH8Y9C;AG7YmC;EAAW,iBAAA;CHgZ9C;AG/YmC;EAAW,iBAAA;CHkZ9C;AGjZmC;EAAW,iBAAA;CHoZ9C;AGnZmC;EAAW,iBAAA;CHsZ9C;AGrZmC;EAAW,iBAAA;CHwZ9C;AGvZmC;EAAW,iBAAA;CH0Z9C;AGzZmC;EAAW,iBAAA;CH4Z9C;AG3ZmC;EAAW,iBAAA;CH8Z9C;AG7ZmC;EAAW,iBAAA;CHga9C;AG/ZmC;EAAW,iBAAA;CHka9C;AGjamC;EAAW,iBAAA;CHoa9C;AGnamC;EAAW,iBAAA;CHsa9C;AGramC;EAAW,iBAAA;CHwa9C;AGvamC;EAAW,iBAAA;CH0a9C;AGzamC;EAAW,iBAAA;CH4a9C;AG3amC;EAAW,iBAAA;CH8a9C;AG7amC;EAAW,iBAAA;CHgb9C;AG/amC;EAAW,iBAAA;CHkb9C;AGjbmC;EAAW,iBAAA;CHob9C;AGnbmC;EAAW,iBAAA;CHsb9C;AGrbmC;EAAW,iBAAA;CHwb9C;AGvbmC;EAAW,iBAAA;CH0b9C;AGzbmC;EAAW,iBAAA;CH4b9C;AG3bmC;EAAW,iBAAA;CH8b9C;AG7bmC;EAAW,iBAAA;CHgc9C;AG/bmC;EAAW,iBAAA;CHkc9C;AGjcmC;EAAW,iBAAA;CHoc9C;AGncmC;EAAW,iBAAA;CHsc9C;AGrcmC;EAAW,iBAAA;CHwc9C;AGvcmC;EAAW,iBAAA;CH0c9C;AGzcmC;EAAW,iBAAA;CH4c9C;AG3cmC;EAAW,iBAAA;CH8c9C;AG7cmC;EAAW,iBAAA;CHgd9C;AG/cmC;EAAW,iBAAA;CHkd9C;AGjdmC;EAAW,iBAAA;CHod9C;AGndmC;EAAW,iBAAA;CHsd9C;AGrdmC;EAAW,iBAAA;CHwd9C;AGvdmC;EAAW,iBAAA;CH0d9C;AGzdmC;EAAW,iBAAA;CH4d9C;AG3dmC;EAAW,iBAAA;CH8d9C;AG7dmC;EAAW,iBAAA;CHge9C;AG/dmC;EAAW,iBAAA;CHke9C;AGjemC;EAAW,iBAAA;CHoe9C;AGnemC;EAAW,iBAAA;CHse9C;AGremC;EAAW,iBAAA;CHwe9C;AGvemC;EAAW,iBAAA;CH0e9C;AGzemC;EAAW,iBAAA;CH4e9C;AG3emC;EAAW,iBAAA;CH8e9C;AG7emC;EAAW,iBAAA;CHgf9C;AG/emC;EAAW,iBAAA;CHkf9C;AGjfmC;EAAW,iBAAA;CHof9C;AGnfmC;EAAW,iBAAA;CHsf9C;AGrfmC;EAAW,iBAAA;CHwf9C;AGvfmC;EAAW,iBAAA;CH0f9C;AGzfmC;EAAW,iBAAA;CH4f9C;AG3fmC;EAAW,iBAAA;CH8f9C;AG7fmC;EAAW,iBAAA;CHggB9C;AG/fmC;EAAW,iBAAA;CHkgB9C;AGjgBmC;EAAW,iBAAA;CHogB9C;AGngBmC;EAAW,iBAAA;CHsgB9C;AGrgBmC;EAAW,iBAAA;CHwgB9C;AGvgBmC;EAAW,iBAAA;CH0gB9C;AGzgBmC;EAAW,iBAAA;CH4gB9C;AG3gBmC;EAAW,iBAAA;CH8gB9C;AG7gBmC;EAAW,iBAAA;CHghB9C;AG/gBmC;EAAW,iBAAA;CHkhB9C;AGjhBmC;EAAW,iBAAA;CHohB9C;AGnhBmC;EAAW,iBAAA;CHshB9C;AGrhBmC;EAAW,iBAAA;CHwhB9C;AGvhBmC;EAAW,iBAAA;CH0hB9C;AGzhBmC;EAAW,iBAAA;CH4hB9C;AG3hBmC;EAAW,iBAAA;CH8hB9C;AG7hBmC;EAAW,iBAAA;CHgiB9C;AG/hBmC;EAAW,iBAAA;CHkiB9C;AGjiBmC;EAAW,iBAAA;CHoiB9C;AGniBmC;EAAW,iBAAA;CHsiB9C;AGriBmC;EAAW,iBAAA;CHwiB9C;AGviBmC;EAAW,iBAAA;CH0iB9C;AGziBmC;EAAW,iBAAA;CH4iB9C;AG3iBmC;EAAW,iBAAA;CH8iB9C;AG7iBmC;EAAW,iBAAA;CHgjB9C;AG/iBmC;EAAW,iBAAA;CHkjB9C;AGjjBmC;EAAW,iBAAA;CHojB9C;AGnjBmC;EAAW,iBAAA;CHsjB9C;AGrjBmC;EAAW,iBAAA;CHwjB9C;AGvjBmC;EAAW,iBAAA;CH0jB9C;AGzjBmC;EAAW,iBAAA;CH4jB9C;AG3jBmC;EAAW,iBAAA;CH8jB9C;AG7jBmC;EAAW,iBAAA;CHgkB9C;AG/jBmC;EAAW,iBAAA;CHkkB9C;AGjkBmC;EAAW,iBAAA;CHokB9C;AGnkBmC;EAAW,iBAAA;CHskB9C;AGrkBmC;EAAW,iBAAA;CHwkB9C;AGvkBmC;EAAW,iBAAA;CH0kB9C;AGzkBmC;EAAW,iBAAA;CH4kB9C;AG3kBmC;EAAW,iBAAA;CH8kB9C;AG7kBmC;EAAW,iBAAA;CHglB9C;AG/kBmC;EAAW,iBAAA;CHklB9C;AGjlBmC;EAAW,iBAAA;CHolB9C;AGnlBmC;EAAW,iBAAA;CHslB9C;AGrlBmC;EAAW,iBAAA;CHwlB9C;AGvlBmC;EAAW,iBAAA;CH0lB9C;AGzlBmC;EAAW,iBAAA;CH4lB9C;AG3lBmC;EAAW,iBAAA;CH8lB9C;AG7lBmC;EAAW,iBAAA;CHgmB9C;AG/lBmC;EAAW,iBAAA;CHkmB9C;AGjmBmC;EAAW,iBAAA;CHomB9C;AGnmBmC;EAAW,iBAAA;CHsmB9C;AGrmBmC;EAAW,iBAAA;CHwmB9C;AGvmBmC;EAAW,iBAAA;CH0mB9C;AGzmBmC;EAAW,iBAAA;CH4mB9C;AG3mBmC;EAAW,iBAAA;CH8mB9C;AG7mBmC;EAAW,iBAAA;CHgnB9C;AG/mBmC;EAAW,iBAAA;CHknB9C;AGjnBmC;EAAW,iBAAA;CHonB9C;AGnnBmC;EAAW,iBAAA;CHsnB9C;AGrnBmC;EAAW,iBAAA;CHwnB9C;AGvnBmC;EAAW,iBAAA;CH0nB9C;AGznBmC;EAAW,iBAAA;CH4nB9C;AG3nBmC;EAAW,iBAAA;CH8nB9C;AG7nBmC;EAAW,iBAAA;CHgoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AGvoBmC;EAAW,iBAAA;CH0oB9C;AGzoBmC;EAAW,iBAAA;CH4oB9C;AG3oBmC;EAAW,iBAAA;CH8oB9C;AG7oBmC;EAAW,iBAAA;CHgpB9C;AG/oBmC;EAAW,iBAAA;CHkpB9C;AGjpBmC;EAAW,iBAAA;CHopB9C;AGnpBmC;EAAW,iBAAA;CHspB9C;AGrpBmC;EAAW,iBAAA;CHwpB9C;AGvpBmC;EAAW,iBAAA;CH0pB9C;AGzpBmC;EAAW,iBAAA;CH4pB9C;AG3pBmC;EAAW,iBAAA;CH8pB9C;AG7pBmC;EAAW,iBAAA;CHgqB9C;AG/pBmC;EAAW,iBAAA;CHkqB9C;AGjqBmC;EAAW,iBAAA;CHoqB9C;AGnqBmC;EAAW,iBAAA;CHsqB9C;AGrqBmC;EAAW,iBAAA;CHwqB9C;AGvqBmC;EAAW,iBAAA;CH0qB9C;AGzqBmC;EAAW,iBAAA;CH4qB9C;AG3qBmC;EAAW,iBAAA;CH8qB9C;AG7qBmC;EAAW,iBAAA;CHgrB9C;AG/qBmC;EAAW,iBAAA;CHkrB9C;AGjrBmC;EAAW,iBAAA;CHorB9C;AGnrBmC;EAAW,iBAAA;CHsrB9C;AGrrBmC;EAAW,iBAAA;CHwrB9C;AGvrBmC;EAAW,iBAAA;CH0rB9C;AGzrBmC;EAAW,iBAAA;CH4rB9C;AG3rBmC;EAAW,iBAAA;CH8rB9C;AG7rBmC;EAAW,iBAAA;CHgsB9C;AG/rBmC;EAAW,iBAAA;CHksB9C;AGjsBmC;EAAW,iBAAA;CHosB9C;AGnsBmC;EAAW,iBAAA;CHssB9C;AGrsBmC;EAAW,iBAAA;CHwsB9C;AGvsBmC;EAAW,iBAAA;CH0sB9C;AGzsBmC;EAAW,iBAAA;CH4sB9C;AG3sBmC;EAAW,iBAAA;CH8sB9C;AG7sBmC;EAAW,iBAAA;CHgtB9C;AG/sBmC;EAAW,iBAAA;CHktB9C;AGjtBmC;EAAW,iBAAA;CHotB9C;AGntBmC;EAAW,iBAAA;CHstB9C;AGrtBmC;EAAW,iBAAA;CHwtB9C;AGvtBmC;EAAW,iBAAA;CH0tB9C;AGztBmC;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ukDH;AexkDC;EACE,oBAAA;Cf0kDH;Ae3kDC;EACE,WAAA;Cf6kDH;Ae9kDC;EACE,oBAAA;CfglDH;AejlDC;EACE,mBAAA;CfmlDH;Ae/kDC;EACE,YAAA;CfilDH;AejmDC;EACE,WAAA;CfmmDH;AepmDC;EACE,mBAAA;CfsmDH;AevmDC;EACE,mBAAA;CfymDH;Ae1mDC;EACE,UAAA;Cf4mDH;Ae7mDC;EACE,mBAAA;Cf+mDH;AehnDC;EACE,mBAAA;CfknDH;AennDC;EACE,UAAA;CfqnDH;AetnDC;EACE,mBAAA;CfwnDH;AeznDC;EACE,mBAAA;Cf2nDH;Ae5nDC;EACE,UAAA;Cf8nDH;Ae/nDC;EACE,mBAAA;CfioDH;AeloDC;EACE,kBAAA;CfooDH;AehoDC;EACE,WAAA;CfkoDH;AepnDC;EACE,kBAAA;CfsnDH;AevnDC;EACE,0BAAA;CfynDH;Ae1nDC;EACE,0BAAA;Cf4nDH;Ae7nDC;EACE,iBAAA;Cf+nDH;AehoDC;EACE,0BAAA;CfkoDH;AenoDC;EACE,0BAAA;CfqoDH;AetoDC;EACE,iBAAA;CfwoDH;AezoDC;EACE,0BAAA;Cf2oDH;Ae5oDC;EACE,0BAAA;Cf8oDH;Ae/oDC;EACE,iBAAA;CfipDH;AelpDC;EACE,0BAAA;CfopDH;AerpDC;EACE,yBAAA;CfupDH;AexpDC;EACE,gBAAA;Cf0pDH;Aa1pDD;EElCI;IACE,YAAA;Gf+rDH;EexrDD;IACE,YAAA;Gf0rDD;Ee3rDD;IACE,oBAAA;Gf6rDD;Ee9rDD;IACE,oBAAA;GfgsDD;EejsDD;IACE,WAAA;GfmsDD;EepsDD;IACE,oBAAA;GfssDD;EevsDD;IACE,oBAAA;GfysDD;Ee1sDD;IACE,WAAA;Gf4sDD;Ee7sDD;IACE,oBAAA;Gf+sDD;EehtDD;IACE,oBAAA;GfktDD;EentDD;IACE,WAAA;GfqtDD;EettDD;IACE,oBAAA;GfwtDD;EeztDD;IACE,mBAAA;Gf2tDD;Ee7sDD;IACE,YAAA;Gf+sDD;EehtDD;IACE,oBAAA;GfktDD;EentDD;IACE,oBAAA;GfqtDD;EettDD;IACE,WAAA;GfwtDD;EeztDD;IACE,oBAAA;Gf2tDD;Ee5tDD;IACE,oBAAA;Gf8tDD;Ee/tDD;IACE,WAAA;GfiuDD;EeluDD;IACE,oBAAA;GfouDD;EeruDD;IACE,oBAAA;GfuuDD;EexuDD;IACE,WAAA;Gf0uDD;Ee3uDD;IACE,oBAAA;Gf6uDD;Ee9uDD;IACE,mBAAA;GfgvDD;Ee5uDD;IACE,YAAA;Gf8uDD;Ee9vDD;IACE,WAAA;GfgwDD;EejwDD;IACE,mBAAA;GfmwDD;EepwDD;IACE,mBAAA;GfswDD;EevwDD;IACE,UAAA;GfywDD;Ee1wDD;IACE,mBAAA;Gf4wDD;Ee7wDD;IACE,mBAAA;Gf+wDD;EehxDD;IACE,UAAA;GfkxDD;EenxDD;IACE,mBAAA;GfqxDD;EetxDD;IACE,mBAAA;GfwxDD;EezxDD;IACE,UAAA;Gf2xDD;Ee5xDD;IACE,mBAAA;Gf8xDD;Ee/xDD;IACE,kBAAA;GfiyDD;Ee7xDD;IACE,WAAA;Gf+xDD;EejxDD;IACE,kBAAA;GfmxDD;EepxDD;IACE,0BAAA;GfsxDD;EevxDD;IACE,0BAAA;GfyxDD;Ee1xDD;IACE,iBAAA;Gf4xDD;Ee7xDD;IACE,0BAAA;Gf+xDD;EehyDD;IACE,0BAAA;GfkyDD;EenyDD;IACE,iBAAA;GfqyDD;EetyDD;IACE,0BAAA;GfwyDD;EezyDD;IACE,0BAAA;Gf2yDD;Ee5yDD;IACE,iBAAA;Gf8yDD;Ee/yDD;IACE,0BAAA;GfizDD;EelzDD;IACE,yBAAA;GfozDD;EerzDD;IACE,gBAAA;GfuzDD;CACF;Aa/yDD;EE3CI;IACE,YAAA;Gf61DH;Eet1DD;IACE,YAAA;Gfw1DD;Eez1DD;IACE,oBAAA;Gf21DD;Ee51DD;IACE,oBAAA;Gf81DD;Ee/1DD;IACE,WAAA;Gfi2DD;Eel2DD;IACE,oBAAA;Gfo2DD;Eer2DD;IACE,oBAAA;Gfu2DD;Eex2DD;IACE,WAAA;Gf02DD;Ee32DD;IACE,oBAAA;Gf62DD;Ee92DD;IACE,oBAAA;Gfg3DD;Eej3DD;IACE,WAAA;Gfm3DD;Eep3DD;IACE,oBAAA;Gfs3DD;Eev3DD;IACE,mBAAA;Gfy3DD;Ee32DD;IACE,YAAA;Gf62DD;Ee92DD;IACE,oBAAA;Gfg3DD;Eej3DD;IACE,oBAAA;Gfm3DD;Eep3DD;IACE,WAAA;Gfs3DD;Eev3DD;IACE,oBAAA;Gfy3DD;Ee13DD;IACE,oBAAA;Gf43DD;Ee73DD;IACE,WAAA;Gf+3DD;Eeh4DD;IACE,oBAAA;Gfk4DD;Een4DD;IACE,oBAAA;Gfq4DD;Eet4DD;IACE,WAAA;Gfw4DD;Eez4DD;IACE,oBAAA;Gf24DD;Ee54DD;IACE,mBAAA;Gf84DD;Ee14DD;IACE,YAAA;Gf44DD;Ee55DD;IACE,WAAA;Gf85DD;Ee/5DD;IACE,mBAAA;Gfi6DD;Eel6DD;IACE,mBAAA;Gfo6DD;Eer6DD;IACE,UAAA;Gfu6DD;Eex6DD;IACE,mBAAA;Gf06DD;Ee36DD;IACE,mBAAA;Gf66DD;Ee96DD;IACE,UAAA;Gfg7DD;Eej7DD;IACE,mBAAA;Gfm7DD;Eep7DD;IACE,mBAAA;Gfs7DD;Eev7DD;IACE,UAAA;Gfy7DD;Ee17DD;IACE,mBAAA;Gf47DD;Ee77DD;IACE,kBAAA;Gf+7DD;Ee37DD;IACE,WAAA;Gf67DD;Ee/6DD;IACE,kBAAA;Gfi7DD;Eel7DD;IACE,0BAAA;Gfo7DD;Eer7DD;IACE,0BAAA;Gfu7DD;Eex7DD;IACE,iBAAA;Gf07DD;Ee37DD;IACE,0BAAA;Gf67DD;Ee97DD;IACE,0BAAA;Gfg8DD;Eej8DD;IACE,iBAAA;Gfm8DD;Eep8DD;IACE,0BAAA;Gfs8DD;Eev8DD;IACE,0BAAA;Gfy8DD;Ee18DD;IACE,iBAAA;Gf48DD;Ee78DD;IACE,0BAAA;Gf+8DD;Eeh9DD;IACE,yBAAA;Gfk9DD;Een9DD;IACE,gBAAA;Gfq9DD;CACF;Aa18DD;EE9CI;IACE,YAAA;Gf2/DH;Eep/DD;IACE,YAAA;Gfs/DD;Eev/DD;IACE,oBAAA;Gfy/DD;Ee1/DD;IACE,oBAAA;Gf4/DD;Ee7/DD;IACE,WAAA;Gf+/DD;EehgED;IACE,oBAAA;GfkgED;EengED;IACE,oBAAA;GfqgED;EetgED;IACE,WAAA;GfwgED;EezgED;IACE,oBAAA;Gf2gED;Ee5gED;IACE,oBAAA;Gf8gED;Ee/gED;IACE,WAAA;GfihED;EelhED;IACE,oBAAA;GfohED;EerhED;IACE,mBAAA;GfuhED;EezgED;IACE,YAAA;Gf2gED;Ee5gED;IACE,oBAAA;Gf8gED;Ee/gED;IACE,oBAAA;GfihED;EelhED;IACE,WAAA;GfohED;EerhED;IACE,oBAAA;GfuhED;EexhED;IACE,oBAAA;Gf0hED;Ee3hED;IACE,WAAA;Gf6hED;Ee9hED;IACE,oBAAA;GfgiED;EejiED;IACE,oBAAA;GfmiED;EepiED;IACE,WAAA;GfsiED;EeviED;IACE,oBAAA;GfyiED;Ee1iED;IACE,mBAAA;Gf4iED;EexiED;IACE,YAAA;Gf0iED;Ee1jED;IACE,WAAA;Gf4jED;Ee7jED;IACE,mBAAA;Gf+jED;EehkED;IACE,mBAAA;GfkkED;EenkED;IACE,UAAA;GfqkED;EetkED;IACE,mBAAA;GfwkED;EezkED;IACE,mBAAA;Gf2kED;Ee5kED;IACE,UAAA;Gf8kED;Ee/kED;IACE,mBAAA;GfilED;EellED;IACE,mBAAA;GfolED;EerlED;IACE,UAAA;GfulED;EexlED;IACE,mBAAA;Gf0lED;Ee3lED;IACE,kBAAA;Gf6lED;EezlED;IACE,WAAA;Gf2lED;Ee7kED;IACE,kBAAA;Gf+kED;EehlED;IACE,0BAAA;GfklED;EenlED;IACE,0BAAA;GfqlED;EetlED;IACE,iBAAA;GfwlED;EezlED;IACE,0BAAA;Gf2lED;Ee5lED;IACE,0BAAA;Gf8lED;Ee/lED;IACE,iBAAA;GfimED;EelmED;IACE,0BAAA;GfomED;EermED;IACE,0BAAA;GfumED;EexmED;IACE,iBAAA;Gf0mED;Ee3mED;IACE,0BAAA;Gf6mED;Ee9mED;IACE,yBAAA;GfgnED;EejnED;IACE,gBAAA;GfmnED;CACF;AgBvrED;EACE,8BAAA;ChByrED;AgBvrED;EACE,iBAAA;EACA,oBAAA;EACA,eAAA;EACA,iBAAA;ChByrED;AgBvrED;EACE,iBAAA;ChByrED;AgBnrED;EACE,YAAA;EACA,gBA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","file":"bootstrap.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1, .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-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .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-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .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-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n border: 0;\n background-color: transparent;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n min-height: 34px;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #fff;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #fff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #ccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #fff;\n border: 1px solid #ddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #fff;\n border-color: #ddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #fff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #fff;\n line-height: 1;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n text-decoration: none;\n color: #555;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 12px;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 14px;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #fff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #fff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #fff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #fff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #fff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\002a\"; } }\n.glyphicon-plus { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // WebKit-specific. Other browsers will keep their default outline style.\n // (Initially tried to also force default via `outline: initial`,\n // but that seems to erroneously remove the outline in Firefox altogether.)\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @dl-horizontal-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: floor((@gutter / 2));\n padding-right: ceil((@gutter / 2));\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: ceil((@gutter / -2));\n margin-right: floor((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: ceil((@grid-gutter-width / 2));\n padding-right: floor((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius; // Note: This has no effect on s in CSS.\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Unstyle the caret on ``\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n display: inline-block;\n margin-bottom: 0; // For input.btn\n font-weight: @btn-font-weight;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n white-space: nowrap;\n .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base);\n .user-select(none);\n\n &,\n &:active,\n &.active {\n &:focus,\n &.focus {\n .tab-focus();\n }\n }\n\n &:hover,\n &:focus,\n &.focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n .opacity(.65);\n .box-shadow(none);\n }\n\n a& {\n &.disabled,\n fieldset[disabled] & {\n pointer-events: none; // Future-proof disabling of clicks on `` elements\n }\n }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n border-radius: 0;\n\n &,\n &:active,\n &.active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large);\n}\n.btn-sm {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n.btn-xs {\n .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 25%);\n }\n &:hover {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n\n &:hover,\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 17%);\n border-color: darken(@border, 25%);\n }\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus,\n &.focus {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n\n &.in { display: block; }\n tr&.in { display: table-row; }\n tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition-property(~\"height, visibility\");\n .transition-duration(.35s);\n .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base dashed;\n border-top: @caret-width-base solid ~\"\\9\"; // IE8\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropup,\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n //\n // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n\n // Nuke hover/focus effects\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: @cursor-disabled;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n left: auto; // Reset the default from `.dropdown-menu`\n right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n border-top: 0;\n border-bottom: @caret-width-base dashed;\n border-bottom: @caret-width-base solid ~\"\\9\"; // IE8\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .dropdown-menu-right();\n }\n // Necessary for overrides of the default right aligned menu.\n // Will remove come v4 in all likelihood.\n .dropdown-menu-left {\n .dropdown-menu-left();\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n margin-left: -5px; // Offset the first child's margin\n &:extend(.clearfix all);\n\n .btn,\n .btn-group,\n .input-group {\n float: left;\n }\n > .btn,\n > .btn-group,\n > .input-group {\n margin-left: 5px;\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n .box-shadow(none);\n }\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group,\n > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n &:extend(.clearfix all);\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n .border-top-radius(@btn-border-radius-base);\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n .border-top-radius(0);\n .border-bottom-radius(@btn-border-radius-base);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n > .btn,\n > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n }\n > .btn-group .btn {\n width: 100%;\n }\n\n > .btn-group .dropdown-menu {\n left: auto;\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n > .btn,\n > .btn-group > .btn {\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0,0,0,0);\n pointer-events: none;\n }\n }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n // Ensure that the input is always above the *appended* addon button for\n // proper border colors.\n position: relative;\n z-index: 2;\n\n // IE9 fubars the placeholder attribute in text inputs and the arrows on\n // select elements in input groups. To fix it, we float the input. Details:\n // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n float: left;\n\n width: 100%;\n margin-bottom: 0;\n\n &:focus {\n z-index: 3;\n }\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n color: @input-color;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @input-border-radius;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @input-border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @input-border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n // Jankily prevent input button groups from wrapping with `white-space` and\n // `font-size` in combination with `inline-block` on buttons.\n font-size: 0;\n white-space: nowrap;\n\n // Negative margin for spacing, position for bringing hovered/focused/actived\n // element above the siblings.\n > .btn {\n position: relative;\n + .btn {\n margin-left: -1px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active {\n z-index: 2;\n }\n }\n\n // Negative margin to only have a 1px border between the two\n &:first-child {\n > .btn,\n > .btn-group {\n margin-right: -1px;\n }\n }\n &:last-child {\n > .btn,\n > .btn-group {\n z-index: 2;\n margin-left: -1px;\n }\n }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n margin-bottom: 0;\n padding-left: 0; // Override default ul/ol\n list-style: none;\n &:extend(.clearfix all);\n\n > li {\n position: relative;\n display: block;\n\n > a {\n position: relative;\n display: block;\n padding: @nav-link-padding;\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @nav-link-hover-bg;\n }\n }\n\n // Disabled state sets text to gray and nukes hover/tab effects\n &.disabled > a {\n color: @nav-disabled-link-color;\n\n &:hover,\n &:focus {\n color: @nav-disabled-link-hover-color;\n text-decoration: none;\n background-color: transparent;\n cursor: @cursor-disabled;\n }\n }\n }\n\n // Open dropdowns\n .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @nav-link-hover-bg;\n border-color: @link-color;\n }\n }\n\n // Nav dividers (deprecated with v3.0.1)\n //\n // This should have been removed in v3 with the dropping of `.nav-list`, but\n // we missed it. We don't currently support this anywhere, but in the interest\n // of maintaining backward compatibility in case you use it, it's deprecated.\n .nav-divider {\n .nav-divider();\n }\n\n // Prevent IE8 from misplacing imgs\n //\n // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n > li > a > img {\n max-width: none;\n }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n border-bottom: 1px solid @nav-tabs-border-color;\n > li {\n float: left;\n // Make the list-items overlay the bottom border\n margin-bottom: -1px;\n\n // Actual tabs (as links)\n > a {\n margin-right: 2px;\n line-height: @line-height-base;\n border: 1px solid transparent;\n border-radius: @border-radius-base @border-radius-base 0 0;\n &:hover {\n border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n }\n }\n\n // Active state, and its :hover to override normal :hover\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-tabs-active-link-hover-color;\n background-color: @nav-tabs-active-link-hover-bg;\n border: 1px solid @nav-tabs-active-link-hover-border-color;\n border-bottom-color: transparent;\n cursor: default;\n }\n }\n }\n // pulling this in mainly for less shorthand\n &.nav-justified {\n .nav-justified();\n .nav-tabs-justified();\n }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n > li {\n float: left;\n\n // Links rendered as pills\n > a {\n border-radius: @nav-pills-border-radius;\n }\n + li {\n margin-left: 2px;\n }\n\n // Active state\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-pills-active-link-hover-color;\n background-color: @nav-pills-active-link-hover-bg;\n }\n }\n }\n}\n\n\n// Stacked pills\n.nav-stacked {\n > li {\n float: none;\n + li {\n margin-top: 2px;\n margin-left: 0; // no need for this gap between nav items\n }\n }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n width: 100%;\n\n > li {\n float: none;\n > a {\n text-align: center;\n margin-bottom: 5px;\n }\n }\n\n > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n }\n\n @media (min-width: @screen-sm-min) {\n > li {\n display: table-cell;\n width: 1%;\n > a {\n margin-bottom: 0;\n }\n }\n }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n border-bottom: 0;\n\n > li > a {\n // Override margin from .nav-tabs\n margin-right: 0;\n border-radius: @border-radius-base;\n }\n\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border: 1px solid @nav-tabs-justified-link-border-color;\n }\n\n @media (min-width: @screen-sm-min) {\n > li > a {\n border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n border-radius: @border-radius-base @border-radius-base 0 0;\n }\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border-bottom-color: @nav-tabs-justified-active-link-border-color;\n }\n }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n // make dropdown border overlap tab border\n margin-top: -1px;\n // Remove the top rounded corners here since there is a hard edge above the menu\n .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n margin-bottom: @navbar-margin-bottom;\n border: 1px solid transparent;\n\n // Prevent floats from breaking the navbar\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: @navbar-border-radius;\n }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n overflow-x: visible;\n padding-right: @navbar-padding-horizontal;\n padding-left: @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n &:extend(.clearfix all);\n -webkit-overflow-scrolling: touch;\n\n &.in {\n overflow-y: auto;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border-top: 0;\n box-shadow: none;\n\n &.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0; // Override default setting\n overflow: visible !important;\n }\n\n &.in {\n overflow-y: visible;\n }\n\n // Undo the collapse side padding for navbars with containers to ensure\n // alignment of right-aligned contents.\n .navbar-fixed-top &,\n .navbar-static-top &,\n .navbar-fixed-bottom & {\n padding-left: 0;\n padding-right: 0;\n }\n }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n .navbar-collapse {\n max-height: @navbar-collapse-max-height;\n\n @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n max-height: 200px;\n }\n }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n > .navbar-header,\n > .navbar-collapse {\n margin-right: -@navbar-padding-horizontal;\n margin-left: -@navbar-padding-horizontal;\n\n @media (min-width: @grid-float-breakpoint) {\n margin-right: 0;\n margin-left: 0;\n }\n }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n z-index: @zindex-navbar;\n border-width: 0 0 1px;\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: @zindex-navbar-fixed;\n\n // Undo the rounded corners\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0; // override .navbar defaults\n border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n float: left;\n padding: @navbar-padding-vertical @navbar-padding-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-computed;\n height: @navbar-height;\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n\n > img {\n display: block;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n .navbar > .container &,\n .navbar > .container-fluid & {\n margin-left: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: @navbar-padding-horizontal;\n padding: 9px 10px;\n .navbar-vertical-align(34px);\n background-color: transparent;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n\n // We remove the `outline` here, but later compensate by attaching `:hover`\n // styles to `:focus`.\n &:focus {\n outline: 0;\n }\n\n // Bars\n .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n }\n .icon-bar + .icon-bar {\n margin-top: 4px;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n display: none;\n }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: @line-height-computed;\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n > li > a,\n .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n > li > a {\n line-height: @line-height-computed;\n &:hover,\n &:focus {\n background-image: none;\n }\n }\n }\n }\n\n // Uncollapse the nav\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin: 0;\n\n > li {\n float: left;\n > a {\n padding-top: @navbar-padding-vertical;\n padding-bottom: @navbar-padding-vertical;\n }\n }\n }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n margin-left: -@navbar-padding-horizontal;\n margin-right: -@navbar-padding-horizontal;\n padding: 10px @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n\n // Mixin behavior for optimum display\n .form-inline();\n\n .form-group {\n @media (max-width: @grid-float-breakpoint-max) {\n margin-bottom: 5px;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n }\n\n // Vertically center in expanded, horizontal navbar\n .navbar-vertical-align(@input-height-base);\n\n // Undo 100% width for pull classes\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n .box-shadow(none);\n }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n .border-top-radius(@navbar-border-radius);\n .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n .navbar-vertical-align(@input-height-base);\n\n &.btn-sm {\n .navbar-vertical-align(@input-height-small);\n }\n &.btn-xs {\n .navbar-vertical-align(22);\n }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n .navbar-vertical-align(@line-height-computed);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin-left: @navbar-padding-horizontal;\n margin-right: @navbar-padding-horizontal;\n }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-left { .pull-left(); }\n .navbar-right {\n .pull-right();\n margin-right: -@navbar-padding-horizontal;\n\n ~ .navbar-right {\n margin-right: 0;\n }\n }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n background-color: @navbar-default-bg;\n border-color: @navbar-default-border;\n\n .navbar-brand {\n color: @navbar-default-brand-color;\n &:hover,\n &:focus {\n color: @navbar-default-brand-hover-color;\n background-color: @navbar-default-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-default-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-default-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n\n .navbar-toggle {\n border-color: @navbar-default-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-default-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-default-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: @navbar-default-border;\n }\n\n // Dropdown menu items\n .navbar-nav {\n // Remove background color from open dropdown\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-default-link-active-bg;\n color: @navbar-default-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n > li > a {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n }\n }\n\n\n // Links in navbars\n //\n // Add a class to ensure links outside the navbar nav are colored correctly.\n\n .navbar-link {\n color: @navbar-default-link-color;\n &:hover {\n color: @navbar-default-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n }\n }\n }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n background-color: @navbar-inverse-bg;\n border-color: @navbar-inverse-border;\n\n .navbar-brand {\n color: @navbar-inverse-brand-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-brand-hover-color;\n background-color: @navbar-inverse-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-inverse-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-inverse-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n\n // Darken the responsive nav toggle\n .navbar-toggle {\n border-color: @navbar-inverse-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-inverse-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-inverse-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: darken(@navbar-inverse-bg, 7%);\n }\n\n // Dropdowns\n .navbar-nav {\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-inverse-link-active-bg;\n color: @navbar-inverse-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display\n .open .dropdown-menu {\n > .dropdown-header {\n border-color: @navbar-inverse-border;\n }\n .divider {\n background-color: @navbar-inverse-border;\n }\n > li > a {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n }\n }\n\n .navbar-link {\n color: @navbar-inverse-link-color;\n &:hover {\n color: @navbar-inverse-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n }\n }\n }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n .clearfix();\n}\n.center-block {\n .center-block();\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n display: none !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n\n > li {\n display: inline-block;\n\n + li:before {\n content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: @line-height-computed 0;\n border-radius: @border-radius-base;\n\n > li {\n display: inline; // Remove list-style and block-level defaults\n > a,\n > span {\n position: relative;\n float: left; // Collapse white-space\n padding: @padding-base-vertical @padding-base-horizontal;\n line-height: @line-height-base;\n text-decoration: none;\n color: @pagination-color;\n background-color: @pagination-bg;\n border: 1px solid @pagination-border;\n margin-left: -1px;\n }\n &:first-child {\n > a,\n > span {\n margin-left: 0;\n .border-left-radius(@border-radius-base);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius-base);\n }\n }\n }\n\n > li > a,\n > li > span {\n &:hover,\n &:focus {\n z-index: 2;\n color: @pagination-hover-color;\n background-color: @pagination-hover-bg;\n border-color: @pagination-hover-border;\n }\n }\n\n > .active > a,\n > .active > span {\n &,\n &:hover,\n &:focus {\n z-index: 3;\n color: @pagination-active-color;\n background-color: @pagination-active-bg;\n border-color: @pagination-active-border;\n cursor: default;\n }\n }\n\n > .disabled {\n > span,\n > span:hover,\n > span:focus,\n > a,\n > a:hover,\n > a:focus {\n color: @pagination-disabled-color;\n background-color: @pagination-disabled-bg;\n border-color: @pagination-disabled-border;\n cursor: @cursor-disabled;\n }\n }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @line-height-computed 0;\n list-style: none;\n text-align: center;\n &:extend(.clearfix all);\n li {\n display: inline;\n > a,\n > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: @pager-bg;\n border: 1px solid @pager-border;\n border-radius: @pager-border-radius;\n }\n\n > a:hover,\n > a:focus {\n text-decoration: none;\n background-color: @pager-hover-bg;\n }\n }\n\n .next {\n > a,\n > span {\n float: right;\n }\n }\n\n .previous {\n > a,\n > span {\n float: left;\n }\n }\n\n .disabled {\n > a,\n > a:hover,\n > a:focus,\n > span {\n color: @pager-disabled-color;\n background-color: @pager-bg;\n cursor: @cursor-disabled;\n }\n }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n a& {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for labels in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n background-color: @color;\n\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for badges in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n\n .btn-xs &,\n .btn-group-xs > .btn & {\n top: 0;\n padding: 1px 5px;\n }\n\n // Hover state, but only for links\n a& {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Account for badges in navs\n .list-group-item.active > &,\n .nav-pills > .active > a > & {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n }\n\n .list-group-item > & {\n float: right;\n }\n\n .list-group-item > & + & {\n margin-right: 5px;\n }\n\n .nav-pills > li > a > & {\n margin-left: 3px;\n }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding-top: @jumbotron-padding;\n padding-bottom: @jumbotron-padding;\n margin-bottom: @jumbotron-padding;\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1,\n .h1 {\n color: @jumbotron-heading-color;\n }\n\n p {\n margin-bottom: (@jumbotron-padding / 2);\n font-size: @jumbotron-font-size;\n font-weight: 200;\n }\n\n > hr {\n border-top-color: darken(@jumbotron-bg, 10%);\n }\n\n .container &,\n .container-fluid & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n\n .container {\n max-width: 100%;\n }\n\n @media screen and (min-width: @screen-sm-min) {\n padding-top: (@jumbotron-padding * 1.6);\n padding-bottom: (@jumbotron-padding * 1.6);\n\n .container &,\n .container-fluid & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1,\n .h1 {\n font-size: @jumbotron-heading-font-size;\n }\n }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n display: block;\n padding: @thumbnail-padding;\n margin-bottom: @line-height-computed;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(border .2s ease-in-out);\n\n > img,\n a > img {\n &:extend(.img-responsive);\n margin-left: auto;\n margin-right: auto;\n }\n\n // Add a hover state for linked versions only\n a&:hover,\n a&:focus,\n a&.active {\n border-color: @link-color;\n }\n\n // Image captions\n .caption {\n padding: @thumbnail-caption-padding;\n color: @thumbnail-caption-color;\n }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headings-color\n color: inherit;\n }\n\n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n\n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n overflow: hidden;\n height: @line-height-computed;\n margin-bottom: @line-height-computed;\n background-color: @progress-bg;\n border-radius: @progress-border-radius;\n .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: @font-size-small;\n line-height: @line-height-computed;\n color: @progress-bar-color;\n text-align: center;\n background-color: @progress-bar-bg;\n .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n #gradient > .striped();\n background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n background-color: @color;\n\n // Deprecated parent class requirement as of v3.2.0\n .progress-striped & {\n #gradient > .striped();\n }\n}\n",".media {\n // Proper spacing between instances of .media\n margin-top: 15px;\n\n &:first-child {\n margin-top: 0;\n }\n}\n\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n\n.media-body {\n width: 10000px;\n}\n\n.media-object {\n display: block;\n\n // Fix collapse in webkit from max-width: 100% and display: table-cell.\n &.img-thumbnail {\n max-width: none;\n }\n}\n\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n\n.media-middle {\n vertical-align: middle;\n}\n\n.media-bottom {\n vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on

>>0){m=a+1204|0;do{l=e+j|0;k=n+(l*216|0)+196|0;if(!(c[k>>2]|0)){Cc(n+(l*216|0)|0,b,g,e,d,f);c[k>>2]=1;c[m>>2]=(c[m>>2]|0)+1}e=e+1|0}while((e|0)!=(p|0))}if(g){if(p){n=g+-1|0;h=Z(n,p)|0;e=a+1204|0;l=0-p|0;k=0;do{m=n;j=(c[o>>2]|0)+((k+h|0)*216|0)|0;while(1){Cc(j,b,m,k,d,f);c[j+196>>2]=1;c[e>>2]=(c[e>>2]|0)+1;if(!m)break;else{m=m+-1|0;j=j+(l*216|0)|0}}k=k+1|0}while((k|0)!=(p|0))}}else g=0;g=g+1|0;if(g>>>0>=q>>>0){i=r;return 0}m=a+1204|0;if(!p){i=r;return 0}do{e=c[o>>2]|0;l=Z(g,p)|0;k=0;do{h=k+l|0;j=e+(h*216|0)+196|0;if(!(c[j>>2]|0)){Cc(e+(h*216|0)|0,b,g,k,d,f);c[j>>2]=1;c[m>>2]=(c[m>>2]|0)+1}k=k+1|0}while((k|0)!=(p|0));g=g+1|0}while((g|0)!=(q|0));i=r;return 0}}if((d|0)==2|(d|0)==7)if((c[a+3384>>2]|0)==0|(f|0)==0)g=13;else g=14;else if(!f)g=13;else g=14;if((g|0)==13)id(c[b>>2]|0,128,Z(p*384|0,q)|0);else if((g|0)==14)hd(c[b>>2]|0,f,Z(p*384|0,q)|0);g=c[l>>2]|0;c[a+1204>>2]=g;if(!g){i=r;return 0}e=c[a+1212>>2]|0;f=0;do{c[e+(f*216|0)+8>>2]=1;f=f+1|0}while(f>>>0>>0);i=r;return 0}function Cc(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0;sa=i;i=i+480|0;qa=sa+96|0;ra=sa+32|0;m=sa+24|0;n=sa;na=c[e+4>>2]|0;u=c[e+8>>2]|0;Na(e,(Z(na,f)|0)+g|0);p=c[e>>2]|0;k=f<<4;l=g<<4;o=(Z(f<<8,na)|0)+l|0;c[b+20>>2]=40;c[b+8>>2]=0;c[b>>2]=6;c[b+12>>2]=0;c[b+16>>2]=0;c[b+24>>2]=0;do if((h|0)==2|(h|0)==7)id(qa,0,384);else{c[m>>2]=0;c[n+4>>2]=na;c[n+8>>2]=u;c[n>>2]=j;if(!j){id(qa,0,384);break}dc(qa,m,n,l,k,0,0,16,16);sc(e,qa);i=sa;return}while(0);id(ra,0,64);if((f|0)!=0?(c[b+((0-na|0)*216|0)+196>>2]|0)!=0:0){v=o-(na<<4)|0;E=v|1;D=v|3;E=(d[p+E>>0]|0)+(d[p+v>>0]|0)+(d[p+(E+1)>>0]|0)+(d[p+D>>0]|0)|0;$=v|7;D=(d[p+(D+2)>>0]|0)+(d[p+(D+1)>>0]|0)+(d[p+(D+3)>>0]|0)+(d[p+$>>0]|0)|0;F=(d[p+($+2)>>0]|0)+(d[p+($+1)>>0]|0)+(d[p+($+3)>>0]|0)+(d[p+($+4)>>0]|0)|0;v=(d[p+($+6)>>0]|0)+(d[p+($+5)>>0]|0)+(d[p+($+7)>>0]|0)+(d[p+(v|15)>>0]|0)|0;$=D+E|0;c[ra>>2]=F+$+(c[ra>>2]|0)+v;s=ra+4|0;c[s>>2]=$-F-v+(c[s>>2]|0);s=1}else{E=0;D=0;F=0;v=0;s=0}if((u+-1|0)!=(f|0)?(c[b+(na*216|0)+196>>2]|0)!=0:0){z=o+(na<<8)|0;w=z|1;x=z|3;w=(d[p+w>>0]|0)+(d[p+z>>0]|0)+(d[p+(w+1)>>0]|0)+(d[p+x>>0]|0)|0;r=z|7;x=(d[p+(x+2)>>0]|0)+(d[p+(x+1)>>0]|0)+(d[p+(x+3)>>0]|0)+(d[p+r>>0]|0)|0;y=(d[p+(r+2)>>0]|0)+(d[p+(r+1)>>0]|0)+(d[p+(r+3)>>0]|0)+(d[p+(r+4)>>0]|0)|0;z=(d[p+(r+6)>>0]|0)+(d[p+(r+5)>>0]|0)+(d[p+(r+7)>>0]|0)+(d[p+(z|15)>>0]|0)|0;r=x+w|0;c[ra>>2]=y+r+(c[ra>>2]|0)+z;t=ra+4|0;c[t>>2]=r-y-z+(c[t>>2]|0);t=1;r=s+1|0}else{t=0;w=0;x=0;y=0;z=0;r=s}if((g|0)!=0?(c[b+-20>>2]|0)!=0:0){_=o+-1|0;$=na<<4;j=na<<5;ma=na*48|0;C=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;h=na<<6;_=_+h|0;B=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;_=_+h|0;A=(d[p+(_+$)>>0]|0)+(d[p+_>>0]|0)+(d[p+(_+j)>>0]|0)+(d[p+(_+ma)>>0]|0)|0;h=_+h|0;ma=(d[p+(h+$)>>0]|0)+(d[p+h>>0]|0)+(d[p+(h+j)>>0]|0)+(d[p+(h+ma)>>0]|0)|0;h=B+C|0;c[ra>>2]=A+h+(c[ra>>2]|0)+ma;j=ra+16|0;c[j>>2]=h-A-ma+(c[j>>2]|0);j=r+1|0;h=1}else{j=r;C=0;B=0;A=0;ma=0;h=0}do if((na+-1|0)!=(g|0)?(c[b+412>>2]|0)!=0:0){$=o+16|0;n=na<<4;m=na<<5;o=na*48|0;b=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;q=na<<6;$=$+q|0;l=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;$=$+q|0;k=(d[p+($+n)>>0]|0)+(d[p+$>>0]|0)+(d[p+($+m)>>0]|0)+(d[p+($+o)>>0]|0)|0;q=$+q|0;o=(d[p+(q+n)>>0]|0)+(d[p+q>>0]|0)+(d[p+(q+m)>>0]|0)+(d[p+(q+o)>>0]|0)|0;p=j+1|0;q=h+1|0;j=l+b|0;c[ra>>2]=k+j+(c[ra>>2]|0)+o;m=ra+16|0;j=j-k-o+(c[m>>2]|0)|0;c[m>>2]=j;m=(r|0)==0;n=(h|0)!=0;if(!(m&n)){if(!m){m=1;j=p;h=q;l=21;break}}else c[ra+4>>2]=A+ma+B+C-b-l-k-o>>5;m=1;o=(s|0)!=0;b=(t|0)!=0;h=q;l=27}else l=17;while(0);if((l|0)==17){n=(h|0)!=0;if(!r){m=0;p=j;l=23}else{m=0;l=21}}if((l|0)==21){p=ra+4|0;c[p>>2]=c[p>>2]>>r+3;p=j;l=23}do if((l|0)==23){j=(h|0)==0;o=(s|0)!=0;b=(t|0)!=0;if(j&o&b){c[ra+16>>2]=F+v+D+E-z-y-x-w>>5;pa=m;h=p;oa=n;o=1;b=1;break}if(j){pa=m;h=p;oa=n}else{j=c[ra+16>>2]|0;l=27}}while(0);if((l|0)==27){c[ra+16>>2]=j>>h+3;pa=m;h=p;oa=n}if((h|0)==1)c[ra>>2]=c[ra>>2]>>4;else if((h|0)==2)c[ra>>2]=c[ra>>2]>>5;else if((h|0)==3)c[ra>>2]=(c[ra>>2]|0)*21>>10;else c[ra>>2]=c[ra>>2]>>6;Dc(ra);n=0;j=qa;m=ra;while(1){h=c[m+((n>>>2&3)<<2)>>2]|0;if((h|0)<0)h=0;else h=(h|0)>255?-1:h&255;a[j>>0]=h;h=n+1|0;if((h|0)==256)break;else{n=h;j=j+1|0;m=(h&63|0)==0?m+16|0:m}}ta=Z(u,na)|0;V=na<<3;Y=0-V|0;G=Y|1;_=G+1|0;$=Y|3;aa=$+1|0;ba=$+2|0;ca=$+3|0;da=Y|7;W=ra+4|0;ka=na<<6;H=ka|1;ea=H+1|0;fa=ka|3;ga=fa+1|0;ha=fa+2|0;ia=fa+3|0;ja=ka|7;I=V+-1|0;U=na<<4;J=U+-1|0;K=J+V|0;L=J+U|0;M=L+V|0;N=L+U|0;O=N+V|0;X=ra+16|0;P=V+8|0;Q=U|8;R=Q+V|0;S=Q+U|0;T=S+V|0;U=S+U|0;V=U+V|0;la=ta<<6;q=E;p=D;h=F;t=v;n=w;j=x;l=y;u=z;F=0;m=C;k=B;r=A;s=ma;E=(c[e>>2]|0)+((Z(f<<6,na)|0)+(g<<3)+(ta<<8))|0;while(1){id(ra,0,64);if(o){q=(d[E+G>>0]|0)+(d[E+Y>>0]|0)|0;p=(d[E+$>>0]|0)+(d[E+_>>0]|0)|0;z=(d[E+ba>>0]|0)+(d[E+aa>>0]|0)|0;A=(d[E+da>>0]|0)+(d[E+ca>>0]|0)|0;t=p+q|0;c[ra>>2]=z+t+(c[ra>>2]|0)+A;c[W>>2]=t-z-A+(c[W>>2]|0);t=1}else{z=h;A=t;t=0}if(b){B=(d[E+H>>0]|0)+(d[E+ka>>0]|0)|0;C=(d[E+fa>>0]|0)+(d[E+ea>>0]|0)|0;D=(d[E+ha>>0]|0)+(d[E+ga>>0]|0)|0;u=(d[E+ja>>0]|0)+(d[E+ia>>0]|0)|0;h=C+B|0;c[ra>>2]=D+h+(c[ra>>2]|0)+u;c[W>>2]=h-D-u+(c[W>>2]|0);h=t+1|0}else{B=n;C=j;D=l;h=t}if(oa){v=(d[E+I>>0]|0)+(d[E+-1>>0]|0)|0;w=(d[E+K>>0]|0)+(d[E+J>>0]|0)|0;x=(d[E+M>>0]|0)+(d[E+L>>0]|0)|0;y=(d[E+O>>0]|0)+(d[E+N>>0]|0)|0;t=w+v|0;c[ra>>2]=x+t+(c[ra>>2]|0)+y;c[X>>2]=t-x-y+(c[X>>2]|0);t=h+1|0;s=1}else{t=h;v=m;w=k;x=r;y=s;s=0}do if(pa){l=(d[E+P>>0]|0)+(d[E+8>>0]|0)|0;m=(d[E+R>>0]|0)+(d[E+Q>>0]|0)|0;j=(d[E+T>>0]|0)+(d[E+S>>0]|0)|0;n=(d[E+V>>0]|0)+(d[E+U>>0]|0)|0;t=t+1|0;s=s+1|0;k=m+l|0;c[ra>>2]=j+k+(c[ra>>2]|0)+n;k=k-j-n+(c[X>>2]|0)|0;c[X>>2]=k;r=(h|0)==0;if(!(r&oa))if(r){l=54;break}else{l=49;break}else{c[W>>2]=x+y+w+v-l-m-j-n>>4;l=54;break}}else if(!h){r=s;l=50}else l=49;while(0);if((l|0)==49){c[W>>2]=c[W>>2]>>h+2;r=s;l=50}do if((l|0)==50){l=0;s=(r|0)==0;if(s&o&b){c[X>>2]=z+A+p+q-u-D-C-B>>4;break}if(!s){k=c[X>>2]|0;s=r;l=54}}while(0);if((l|0)==54)c[X>>2]=k>>s+2;if((t|0)==1)c[ra>>2]=c[ra>>2]>>3;else if((t|0)==2)c[ra>>2]=c[ra>>2]>>4;else if((t|0)==3)c[ra>>2]=(c[ra>>2]|0)*21>>9;else c[ra>>2]=c[ra>>2]>>5;Dc(ra);s=0;r=qa+((F<<6)+256)|0;k=ra;while(1){t=c[k+((s>>>1&3)<<2)>>2]|0;if((t|0)<0)t=0;else t=(t|0)>255?-1:t&255;a[r>>0]=t;t=s+1|0;if((t|0)==64)break;else{s=t;r=r+1|0;k=(t&15|0)==0?k+16|0:k}}F=F+1|0;if((F|0)==2)break;else{h=z;t=A;n=B;j=C;l=D;m=v;k=w;r=x;s=y;E=E+la|0}}sc(e,qa);i=sa;return}function Dc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;h=i;f=a+4|0;b=c[f>>2]|0;g=a+16|0;d=c[g>>2]|0;e=c[a>>2]|0;if(!(b|d)){c[a+60>>2]=e;c[a+56>>2]=e;c[a+52>>2]=e;c[a+48>>2]=e;c[a+44>>2]=e;c[a+40>>2]=e;c[a+36>>2]=e;c[a+32>>2]=e;c[a+28>>2]=e;c[a+24>>2]=e;c[a+20>>2]=e;c[g>>2]=e;c[a+12>>2]=e;c[a+8>>2]=e;c[f>>2]=e;i=h;return}else{k=b+e|0;g=b>>1;j=g+e|0;g=e-g|0;b=e-b|0;c[a>>2]=d+k;e=d>>1;c[a+16>>2]=e+k;c[a+32>>2]=k-e;c[a+48>>2]=k-d;c[f>>2]=d+j;c[a+20>>2]=e+j;c[a+36>>2]=j-e;c[a+52>>2]=j-d;c[a+8>>2]=d+g;c[a+24>>2]=e+g;c[a+40>>2]=g-e;c[a+56>>2]=g-d;c[a+12>>2]=d+b;c[a+28>>2]=e+b;c[a+44>>2]=b-e;c[a+60>>2]=b-d;i=h;return}}function Ec(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;h=i;id(b,0,952);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b>>2]=d&1;do if(d){d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+4>>2]=d;if((d|0)==255){d=jb(a,16)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+8>>2]=d;d=jb(a,16)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+12>>2]=d;break}}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+16>>2]=d&1;do if(d){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+20>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+24>>2]=d&1;do if(d){d=jb(a,3)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+28>>2]=d;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+32>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+36>>2]=d&1;if(!d){c[b+40>>2]=2;c[b+44>>2]=2;c[b+48>>2]=2;break}d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+40>>2]=d;d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+44>>2]=d;d=jb(a,8)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+48>>2]=d;break}}else{c[b+28>>2]=5;c[b+40>>2]=2;c[b+44>>2]=2;c[b+48>>2]=2}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+52>>2]=d&1;if(d){d=b+56|0;e=nb(a,d)|0;if(e){d=e;i=h;return d|0}if((c[d>>2]|0)>>>0>5){d=1;i=h;return d|0}d=b+60|0;e=nb(a,d)|0;if(e){d=e;i=h;return d|0}if((c[d>>2]|0)>>>0>5){d=1;i=h;return d|0}}d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+64>>2]=d&1;do if(d){d=kb(a)|0;if((lb(a,32)|0)==-1|(d|0)==0){d=1;i=h;return d|0}c[b+68>>2]=d;d=kb(a)|0;if((lb(a,32)|0)==-1|(d|0)==0){d=1;i=h;return d|0}c[b+72>>2]=d;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+76>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;f=b+80|0;c[f>>2]=d&1;if(d){e=Fc(a,b+84|0)|0;if(e){d=e;i=h;return d|0}}else{c[b+84>>2]=1;c[b+96>>2]=288000001;c[b+224>>2]=288000001;c[b+480>>2]=24;c[b+484>>2]=24;c[b+488>>2]=24;c[b+492>>2]=24}e=jb(a,1)|0;if((e|0)==-1){d=1;i=h;return d|0}e=(e|0)==1;d=b+496|0;c[d>>2]=e&1;if(e){e=Fc(a,b+500|0)|0;if(e){d=e;i=h;return d|0}}else{c[b+500>>2]=1;c[b+512>>2]=240000001;c[b+640>>2]=240000001;c[b+896>>2]=24;c[b+900>>2]=24;c[b+904>>2]=24;c[b+908>>2]=24}if(!((c[f>>2]|0)==0?(c[d>>2]|0)==0:0))g=46;do if((g|0)==46){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}else{c[b+912>>2]=(d|0)==1&1;break}}while(0);d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+916>>2]=(d|0)==1&1;d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}d=(d|0)==1;c[b+920>>2]=d&1;do if(d){d=jb(a,1)|0;if((d|0)==-1){d=1;i=h;return d|0}c[b+924>>2]=(d|0)==1&1;e=b+928|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+932|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+936|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}e=b+940|0;d=nb(a,e)|0;if(d){i=h;return d|0}if((c[e>>2]|0)>>>0>16){d=1;i=h;return d|0}d=nb(a,b+944|0)|0;if(d){i=h;return d|0}d=nb(a,b+948|0)|0;if(!d)break;i=h;return d|0}else{c[b+924>>2]=1;c[b+928>>2]=2;c[b+932>>2]=1;c[b+936>>2]=16;c[b+940>>2]=16;c[b+944>>2]=16;c[b+948>>2]=16}while(0);d=0;i=h;return d|0}function Fc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;d=nb(a,b)|0;if(d){i=k;return d|0}d=(c[b>>2]|0)+1|0;c[b>>2]=d;if(d>>>0>32){d=1;i=k;return d|0}d=jb(a,4)|0;if((d|0)==-1){d=1;i=k;return d|0}j=b+4|0;c[j>>2]=d;e=jb(a,4)|0;if((e|0)==-1){d=1;i=k;return d|0}h=b+8|0;c[h>>2]=e;a:do if(c[b>>2]|0){g=0;while(1){f=b+(g<<2)+12|0;d=nb(a,f)|0;if(d){e=17;break}e=c[f>>2]|0;if((e|0)==-1){d=1;e=17;break}d=e+1|0;c[f>>2]=d;c[f>>2]=d<<(c[j>>2]|0)+6;f=b+(g<<2)+140|0;d=nb(a,f)|0;if(d){e=17;break}e=c[f>>2]|0;if((e|0)==-1){d=1;e=17;break}e=e+1|0;c[f>>2]=e;c[f>>2]=e<<(c[h>>2]|0)+4;e=jb(a,1)|0;if((e|0)==-1){d=1;e=17;break}c[b+(g<<2)+268>>2]=(e|0)==1&1;g=g+1|0;if(g>>>0>=(c[b>>2]|0)>>>0)break a}if((e|0)==17){i=k;return d|0}}while(0);d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+396>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+400>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+404>>2]=d+1;d=jb(a,5)|0;if((d|0)==-1){d=1;i=k;return d|0}c[b+408>>2]=d;d=0;i=k;return d|0}function Gc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;a:do if(!(c[d+284>>2]|0))o=0;else{h=0;while(1){j=c[d+(h*20|0)+288>>2]|0;if((j|0)==5){o=1;break a}else if(!j)break;h=h+1|0}o=0}while(0);j=c[b+16>>2]|0;if((j|0)==1){if((c[e>>2]|0)!=5){f=c[a+12>>2]|0;if((c[a+8>>2]|0)>>>0>(c[d+12>>2]|0)>>>0)f=(c[b+12>>2]|0)+f|0}else f=0;m=c[b+36>>2]|0;h=(m|0)==0;if(h)j=0;else j=(c[d+12>>2]|0)+f|0;e=(c[e+4>>2]|0)==0;k=((e&(j|0)!=0)<<31>>31)+j|0;l=(k|0)!=0;if(l){g=k+-1|0;n=(g>>>0)%(m>>>0)|0;g=(g>>>0)/(m>>>0)|0}else{n=0;g=0}if(h)j=0;else{k=c[b+40>>2]|0;j=0;h=0;do{j=(c[k+(h<<2)>>2]|0)+j|0;h=h+1|0}while(h>>>0>>0)}if(l){g=Z(j,g)|0;k=c[b+40>>2]|0;j=0;do{g=(c[k+(j<<2)>>2]|0)+g|0;j=j+1|0}while(j>>>0<=n>>>0)}else g=0;if(e)j=(c[b+28>>2]|0)+g|0;else j=g;g=(c[d+32>>2]|0)+(c[b+32>>2]|0)|0;h=a+12|0;if(!o){b=((g|0)<0?g:0)+j+(c[d+28>>2]|0)|0;c[h>>2]=f;c[a+8>>2]=c[d+12>>2];i=p;return b|0}else{c[h>>2]=0;c[a+8>>2]=0;b=0;i=p;return b|0}}else if(!j){if((c[e>>2]|0)!=5){h=c[a>>2]|0;j=c[d+20>>2]|0;if(h>>>0>j>>>0?(k=c[b+20>>2]|0,(h-j|0)>>>0>=k>>>1>>>0):0){h=(c[a+4>>2]|0)+k|0;k=a}else{k=a;m=11}}else{c[a+4>>2]=0;c[a>>2]=0;j=c[d+20>>2]|0;h=0;k=a;m=11}do if((m|0)==11){if(j>>>0>h>>>0?(g=c[b+20>>2]|0,(j-h|0)>>>0>g>>>1>>>0):0){h=(c[a+4>>2]|0)-g|0;break}h=c[a+4>>2]|0}while(0);if(!(c[e+4>>2]|0)){b=c[d+24>>2]|0;b=j+h+((b|0)<0?b:0)|0;i=p;return b|0}c[a+4>>2]=h;f=c[d+24>>2]|0;g=(f|0)<0;if(!o){c[k>>2]=j;b=j+h+(g?f:0)|0;i=p;return b|0}else{c[a+4>>2]=0;c[k>>2]=g?0-f|0:0;b=0;i=p;return b|0}}else{if((c[e>>2]|0)==5){k=0;g=0;f=a+12|0}else{j=c[d+12>>2]|0;f=a+12|0;h=c[f>>2]|0;if((c[a+8>>2]|0)>>>0>j>>>0)h=(c[b+12>>2]|0)+h|0;k=h;g=(j+h<<1)+(((c[e+4>>2]|0)==0)<<31>>31)|0}if(!o){c[f>>2]=k;c[a+8>>2]=c[d+12>>2];b=g;i=p;return b|0}else{c[f>>2]=0;c[a+8>>2]=0;b=0;i=p;return b|0}}return 0}function Hc(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;Ab(a);e=fd(2112)|0;c[a+3376>>2]=e;if(e)if(!b)b=0;else{c[a+1216>>2]=1;b=0}else b=1;i=d;return b|0}function Ic(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;i=i+208|0;l=r+204|0;p=r;g=r+112|0;h=r+40|0;q=r+16|0;j=r+12|0;n=r+8|0;c[j>>2]=0;o=a+3344|0;if((c[o>>2]|0)!=0?(c[a+3348>>2]|0)==(b|0):0){b=a+3356|0;c[q+0>>2]=c[b+0>>2];c[q+4>>2]=c[b+4>>2];c[q+8>>2]=c[b+8>>2];c[q+12>>2]=c[b+12>>2];c[q+4>>2]=c[q>>2];c[q+8>>2]=0;c[q+16>>2]=0;c[f>>2]=c[a+3352>>2]}else k=4;do if((k|0)==4)if(!(Pa(b,d,q,f)|0)){d=a+3356|0;c[d+0>>2]=c[q+0>>2];c[d+4>>2]=c[q+4>>2];c[d+8>>2]=c[q+8>>2];c[d+12>>2]=c[q+12>>2];c[d+16>>2]=c[q+16>>2];c[a+3352>>2]=c[f>>2];c[a+3348>>2]=b;break}else{n=3;i=r;return n|0}while(0);c[o>>2]=0;if(sb(q,p)|0){n=3;i=r;return n|0}if(((c[p>>2]|0)+-1|0)>>>0>11){n=0;i=r;return n|0}b=Ib(q,p,a,j)|0;if(!b){do if(!(c[j>>2]|0))k=19;else{if((c[a+1184>>2]|0)!=0?(c[a+16>>2]|0)!=0:0){if(c[a+3380>>2]|0){n=3;i=r;return n|0}if(!(c[a+1188>>2]|0)){m=a+1220|0;n=a+1336|0;c[n>>2]=jc(m)|0;nc(m);Bc(a,n,0)|0}else Bc(a,a+1336|0,c[a+1372>>2]|0)|0;c[f>>2]=0;c[o>>2]=1;c[a+1180>>2]=0;g=a+1336|0;b=a+1360|0;break}c[a+1188>>2]=0;c[a+1180>>2]=0;k=19}while(0);do if((k|0)==19){b=c[p>>2]|0;if((b|0)==7)if(!(Qa(q,g)|0)){Bb(a,g)|0;n=0;i=r;return n|0}else{n=g+40|0;gd(c[n>>2]|0);c[n>>2]=0;n=g+84|0;gd(c[n>>2]|0);c[n>>2]=0;n=3;i=r;return n|0}else if((b|0)==1|(b|0)==5){k=a+1180|0;if(c[a+1180>>2]|0){n=0;i=r;return n|0}c[a+1184>>2]=1;if(Fb(a)|0){c[a+1204>>2]=0;c[a+1208>>2]=e;Ua(q,l)|0;j=a+8|0;d=c[j>>2]|0;b=Db(a,c[l>>2]|0,(c[p>>2]|0)==5&1)|0;if(b){c[a+4>>2]=256;c[a+12>>2]=0;c[j>>2]=32;c[a+16>>2]=0;c[a+3380>>2]=0;n=(b|0)==65535?5:4;i=r;return n|0}if((d|0)!=(c[j>>2]|0)){d=c[a+16>>2]|0;c[n>>2]=1;b=c[a>>2]|0;if(b>>>0<32)b=c[a+(b<<2)+20>>2]|0;else b=0;c[f>>2]=0;c[o>>2]=1;if((((((c[p>>2]|0)==5?(l=_a(n,q,d,c[a+12>>2]|0,5)|0,(c[n>>2]|l|0)==0):0)?(m=a+1220|0,!((c[a+1276>>2]|0)!=0|(b|0)==0)):0)?(c[b+52>>2]|0)==(c[d+52>>2]|0):0)?(c[b+56>>2]|0)==(c[d+56>>2]|0):0)?(c[b+88>>2]|0)==(c[d+88>>2]|0):0)qc(m);else c[a+1280>>2]=0;c[a>>2]=c[j>>2];n=2;i=r;return n|0}}if(c[a+3380>>2]|0){n=3;i=r;return n|0}h=a+1368|0;j=a+2356|0;b=a+16|0;if(Ta(q,j,c[b>>2]|0,c[a+12>>2]|0,p)|0){n=3;i=r;return n|0}if(!(Fb(a)|0))d=a+1220|0;else{d=a+1220|0;if((c[p>>2]|0)!=5?(oc(d,c[a+2368>>2]|0,(c[p+4>>2]|0)!=0&1,c[(c[b>>2]|0)+48>>2]|0)|0)!=0:0){n=3;i=r;return n|0}c[a+1336>>2]=jc(d)|0}od(h|0,j|0,988)|0;c[a+1188>>2]=1;b=a+1360|0;l=p;m=c[l+4>>2]|0;n=b;c[n>>2]=c[l>>2];c[n+4>>2]=m;Hb(a,c[a+1432>>2]|0);nc(d);if(gc(d,a+1436|0,c[a+1380>>2]|0,c[a+1412>>2]|0)|0){n=3;i=r;return n|0}g=a+1336|0;if($a(q,a,g,h)|0){ab(a,c[h>>2]|0);n=3;i=r;return n|0}if(!(Gb(a)|0)){n=0;i=r;return n|0}else{c[k>>2]=1;break}}else if((b|0)==8)if(!(Sa(q,h)|0)){Cb(a,h)|0;n=0;i=r;return n|0}else{n=h+20|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+24|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+28|0;gd(c[n>>2]|0);c[n>>2]=0;n=h+44|0;gd(c[n>>2]|0);c[n>>2]=0;n=3;i=r;return n|0}else{n=0;i=r;return n|0}}while(0);uc(g,c[a+1212>>2]|0);Eb(a);j=Gc(a+1284|0,c[a+16>>2]|0,a+1368|0,b)|0;d=a+1188|0;do if(c[d>>2]|0){h=a+1220|0;if(!(c[a+1364>>2]|0)){hc(h,0,g,c[a+1380>>2]|0,j,(c[b>>2]|0)==5&1,c[a+1208>>2]|0,c[a+1204>>2]|0)|0;break}else{hc(h,a+1644|0,g,c[a+1380>>2]|0,j,(c[b>>2]|0)==5&1,c[a+1208>>2]|0,c[a+1204>>2]|0)|0;break}}while(0);c[a+1184>>2]=0;c[d>>2]=0;n=1;i=r;return n|0}else if((b|0)==65520){n=4;i=r;return n|0}else{n=3;i=r;return n|0}return 0}function Jc(a){a=a|0;var b=0,d=0,e=0,f=0;f=i;e=0;do{d=a+(e<<2)+20|0;b=c[d>>2]|0;if(b){gd(c[b+40>>2]|0);c[(c[d>>2]|0)+40>>2]=0;gd(c[(c[d>>2]|0)+84>>2]|0);c[(c[d>>2]|0)+84>>2]=0;gd(c[d>>2]|0);c[d>>2]=0}e=e+1|0}while((e|0)!=32);e=0;do{d=a+(e<<2)+148|0;b=c[d>>2]|0;if(b){gd(c[b+20>>2]|0);c[(c[d>>2]|0)+20>>2]=0;gd(c[(c[d>>2]|0)+24>>2]|0);c[(c[d>>2]|0)+24>>2]=0;gd(c[(c[d>>2]|0)+28>>2]|0);c[(c[d>>2]|0)+28>>2]=0;gd(c[(c[d>>2]|0)+44>>2]|0);c[(c[d>>2]|0)+44>>2]=0;gd(c[d>>2]|0);c[d>>2]=0}e=e+1|0}while((e|0)!=256);b=a+3376|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+1212|0;gd(c[b>>2]|0);c[b>>2]=0;b=a+1172|0;gd(c[b>>2]|0);c[b>>2]=0;mc(a+1220|0);i=f;return}function Kc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=i;a=pc(a+1220|0)|0;if(!a){a=0;i=f;return a|0}c[b>>2]=c[a+4>>2];c[d>>2]=c[a+12>>2];c[e>>2]=c[a+8>>2];a=c[a>>2]|0;i=f;return a|0}function Lc(a){a=a|0;var b=0;b=i;a=c[a+16>>2]|0;if(!a){a=0;i=b;return a|0}a=c[a+52>>2]|0;i=b;return a|0}function Mc(a){a=a|0;var b=0;b=i;a=c[a+16>>2]|0;if(!a){a=0;i=b;return a|0}a=c[a+56>>2]|0;i=b;return a|0}function Nc(a){a=a|0;var b=0;b=i;qc(a+1220|0);i=b;return}function Oc(a){a=a|0;var b=0;b=i;a=(Jb(a)|0)==0&1;i=b;return a|0}function Pc(a){a=a|0;var b=0,d=0;d=i;a=c[a+16>>2]|0;if(((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(b=c[a+84>>2]|0,(b|0)!=0):0)?(c[b+24>>2]|0)!=0:0)?(c[b+32>>2]|0)!=0:0){a=1;i=d;return a|0}a=0;i=d;return a|0}function Qc(a){a=a|0;var b=0,d=0;d=i;a=c[a+16>>2]|0;if(((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(b=c[a+84>>2]|0,(b|0)!=0):0)?(c[b+24>>2]|0)!=0:0)?(c[b+36>>2]|0)!=0:0)a=c[b+48>>2]|0;else a=2;i=d;return a|0}function Rc(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0;h=i;a=c[a+16>>2]|0;if((a|0)!=0?(c[a+60>>2]|0)!=0:0){c[b>>2]=1;b=a+64|0;c[d>>2]=c[b>>2]<<1;c[e>>2]=(c[a+52>>2]<<4)-((c[a+68>>2]|0)+(c[b>>2]|0)<<1);b=a+72|0;c[f>>2]=c[b>>2]<<1;a=(c[a+56>>2]<<4)-((c[a+76>>2]|0)+(c[b>>2]|0)<<1)|0;c[g>>2]=a;i=h;return}c[b>>2]=0;c[d>>2]=0;c[e>>2]=0;c[f>>2]=0;a=0;c[g>>2]=a;i=h;return}function Sc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;f=i;a=c[a+16>>2]|0;a:do if((((a|0)!=0?(c[a+80>>2]|0)!=0:0)?(e=c[a+84>>2]|0,(e|0)!=0):0)?(c[e>>2]|0)!=0:0){a=c[e+4>>2]|0;do switch(a|0){case 8:{e=11;a=32;break a}case 13:{e=99;a=160;break a}case 12:{e=33;a=64;break a}case 6:{e=11;a=24;break a}case 7:{e=11;a=20;break a}case 255:{a=c[e+8>>2]|0;e=c[e+12>>2]|0;g=(a|0)==0|(e|0)==0;e=g?0:e;a=g?0:a;break a}case 5:{e=33;a=40;break a}case 4:{e=11;a=16;break a}case 3:{e=11;a=10;break a}case 1:case 0:{e=a;break a}case 2:{e=11;a=12;break a}case 10:{e=11;a=18;break a}case 9:{e=33;a=80;break a}case 11:{e=11;a=15;break a}default:{e=0;a=0;break a}}while(0)}else{e=1;a=1}while(0);c[b>>2]=a;c[d>>2]=e;i=f;return}function Tc(a){a=a|0;a=c[a+16>>2]|0;if(!a)a=0;else a=c[a>>2]|0;return a|0}function Uc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;do if(a){d=fd(3396)|0;if(d){e=d+8|0;if(!(Hc(e,b)|0)){c[d>>2]=1;c[d+4>>2]=0;c[a>>2]=d;d=0;break}else{Jc(e);gd(d);d=-4;break}}else d=-4}else d=-1;while(0);i=f;return d|0}function Vc(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;if((a|0)==0|(b|0)==0){a=-1;i=e;return a|0}d=a+8|0;if(!(c[a+24>>2]|0)){a=-6;i=e;return a|0}if(!(c[a+20>>2]|0)){a=-6;i=e;return a|0}c[b+4>>2]=(Lc(d)|0)<<4;c[b+8>>2]=(Mc(d)|0)<<4;c[b+12>>2]=Pc(d)|0;c[b+16>>2]=Qc(d)|0;Rc(d,b+28|0,b+32|0,b+36|0,b+40|0,b+44|0);Sc(d,b+20|0,b+24|0);c[b>>2]=Tc(d)|0;a=0;i=e;return a|0}function Wc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;m=i;i=i+16|0;j=m;a:do if((!((b|0)==0|(d|0)==0)?(f=c[b>>2]|0,(f|0)!=0):0)?(g=c[b+4>>2]|0,(g|0)!=0):0)if((a|0)!=0?(e=c[a>>2]|0,(e|0)!=0):0){c[d>>2]=0;c[j>>2]=0;k=a+8|0;c[a+3392>>2]=c[b+12>>2];h=b+8|0;b=1;while(1){if((e|0)==2){l=8;break}e=Ic(k,f,g,c[h>>2]|0,j)|0;n=c[j>>2]|0;f=f+n|0;g=g-n|0;g=(g|0)<0?0:g;c[d>>2]=f;if((e|0)==5){b=-4;break a}else if((e|0)==4){e=(Oc(k)|0|g|0)==0;b=e?-2:b}else if((e|0)==2)break;else if((e|0)==1){l=13;break}if(!g)break a;e=c[a>>2]|0}if((l|0)==8){c[a>>2]=1;c[d>>2]=f+(c[j>>2]|0)}else if((l|0)==13){b=a+4|0;c[b>>2]=(c[b>>2]|0)+1;b=(g|0)==0?2:3;break}b=a+1288|0;if((c[b>>2]|0)!=0?(c[a+1244>>2]|0)!=(c[a+1248>>2]|0):0){c[b>>2]=0;c[a>>2]=2;b=3}else b=4}else b=-3;else b=-1;while(0);i=m;return b|0}function Xc(a){a=a|0;c[a>>2]=2;c[a+4>>2]=3;return}function Yc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;h=i;i=i+16|0;f=h+8|0;e=h+4|0;g=h;if((a|0)==0|(b|0)==0){a=-1;i=h;return a|0}a=a+8|0;if(d)Nc(a);a=Kc(a,g,e,f)|0;if(!a){a=0;i=h;return a|0}c[b>>2]=a;c[b+4>>2]=c[g>>2];c[b+8>>2]=c[e>>2];c[b+12>>2]=c[f>>2];a=2;i=h;return a|0}function Zc(a){a=a|0;var b=0,d=0;d=i;b=jd(a)|0;c[1792]=b;c[1791]=b;c[1790]=a;c[1793]=b+a;i=d;return b|0}function _c(a){a=a|0;c[1790]=a;return}function $c(){var a=0;a=i;c[1786]=c[1791];c[1787]=c[1790];do bd()|0;while((c[1787]|0)!=0);i=a;return}function ad(){var a=0,b=0;b=i;if(Uc(7176,0)|0){da(7280)|0;a=c[1784]|0;if(a)kd(a)}else{c[1796]=1;c[1798]=1}i=b;return -1}function bd(){var a=0,b=0,d=0;b=i;c[1788]=c[1798];a=Wc(c[1794]|0,7144,7200)|0;switch(a|0){case 1:case -2:{c[1787]=0;i=b;return a|0}case 4:{if(Vc(c[1794]|0,7208)|0){a=-1;i=b;return a|0}c[1814]=(Z((c[1803]|0)*3|0,c[1804]|0)|0)>>>1;ra();a=c[1800]|0;c[1787]=(c[1786]|0)-a+(c[1787]|0);c[1786]=a;a=0;i=b;return a|0}case 2:{c[1787]=0;break}case 3:{d=c[1800]|0;c[1787]=(c[1786]|0)-d+(c[1787]|0);c[1786]=d;break}default:{i=b;return a|0}}c[1798]=(c[1798]|0)+1;if((Yc(c[1794]|0,7264,0)|0)!=2){i=b;return a|0}do{c[1796]=(c[1796]|0)+1;ca(c[1816]|0,c[1803]|0,c[1804]|0)}while((Yc(c[1794]|0,7264,0)|0)==2);i=b;return a|0}function cd(){var a=0,b=0;b=i;a=c[1784]|0;if(a)kd(a);i=b;return}function dd(){var a=0,b=0;b=i;i=i+16|0;a=b;Xc(a);i=b;return c[a>>2]|0}function ed(){var a=0,b=0;b=i;i=i+16|0;a=b;Xc(a);i=b;return c[a+4>>2]|0}function fd(a){a=a|0;var b=0;b=i;a=jd(a)|0;i=b;return a|0}function gd(a){a=a|0;var b=0;b=i;kd(a);i=b;return}function hd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=i;od(a|0,b|0,c|0)|0;i=d;return}function id(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=i;nd(a|0,b&255|0,c|0)|0;i=d;return}function jd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0;L=i;do if(a>>>0<245){if(a>>>0<11)p=16;else p=a+11&-8;a=p>>>3;l=c[1828]|0;k=l>>>a;if(k&3){g=(k&1^1)+a|0;b=g<<1;h=7352+(b<<2)|0;b=7352+(b+2<<2)|0;e=c[b>>2]|0;j=e+8|0;f=c[j>>2]|0;do if((h|0)!=(f|0)){if(f>>>0<(c[1832]|0)>>>0)ka();d=f+12|0;if((c[d>>2]|0)==(e|0)){c[d>>2]=h;c[b>>2]=f;break}else ka()}else c[1828]=l&~(1<>2]=x|3;x=e+(x|4)|0;c[x>>2]=c[x>>2]|1;x=j;i=L;return x|0}j=c[1830]|0;if(p>>>0>j>>>0){if(k){g=2<>>12&16;g=g>>>a;h=g>>>5&8;g=g>>>h;d=g>>>2&4;g=g>>>d;e=g>>>1&2;g=g>>>e;f=g>>>1&1;f=(h|a|d|e|f)+(g>>>f)|0;g=f<<1;e=7352+(g<<2)|0;g=7352+(g+2<<2)|0;d=c[g>>2]|0;a=d+8|0;h=c[a>>2]|0;do if((e|0)!=(h|0)){if(h>>>0<(c[1832]|0)>>>0)ka();j=h+12|0;if((c[j>>2]|0)==(d|0)){c[j>>2]=e;c[g>>2]=h;m=c[1830]|0;break}else ka()}else{c[1828]=l&~(1<>2]=p|3;b=d+p|0;c[d+(p|4)>>2]=k|1;c[d+x>>2]=k;if(m){e=c[1833]|0;g=m>>>3;h=g<<1;f=7352+(h<<2)|0;j=c[1828]|0;g=1<>2]|0;if(h>>>0<(c[1832]|0)>>>0)ka();else{n=j;o=h}}else{c[1828]=j|g;n=7352+(h+2<<2)|0;o=f}c[n>>2]=e;c[o+12>>2]=e;c[e+8>>2]=o;c[e+12>>2]=f}c[1830]=k;c[1833]=b;x=a;i=L;return x|0}k=c[1829]|0;if(k){l=(k&0-k)+-1|0;w=l>>>12&16;l=l>>>w;v=l>>>5&8;l=l>>>v;x=l>>>2&4;l=l>>>x;j=l>>>1&2;l=l>>>j;m=l>>>1&1;m=c[7616+((v|w|x|j|m)+(l>>>m)<<2)>>2]|0;l=(c[m+4>>2]&-8)-p|0;j=m;while(1){d=c[j+16>>2]|0;if(!d){d=c[j+20>>2]|0;if(!d)break}j=(c[d+4>>2]&-8)-p|0;x=j>>>0>>0;l=x?j:l;j=d;m=x?d:m}k=c[1832]|0;if(m>>>0>>0)ka();b=m+p|0;if(m>>>0>=b>>>0)ka();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){e=0;break}}while(1){f=j+20|0;g=c[f>>2]|0;if(g){j=g;h=f;continue}f=j+16|0;g=c[f>>2]|0;if(!g)break;else{j=g;h=f}}if(h>>>0>>0)ka();else{c[h>>2]=0;e=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ka();j=f+12|0;if((c[j>>2]|0)!=(m|0))ka();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;e=g;break}else ka()}while(0);do if(a){j=c[m+28>>2]|0;h=7616+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=e;if(!e){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=e;else c[a+20>>2]=e;if(!e)break}h=c[1832]|0;if(e>>>0>>0)ka();c[e+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ka();else{c[e+16>>2]=j;c[j+24>>2]=e;break}while(0);f=c[m+20>>2]|0;if(f)if(f>>>0<(c[1832]|0)>>>0)ka();else{c[e+20>>2]=f;c[f+24>>2]=e;break}}while(0);if(l>>>0<16){x=l+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}else{c[m+4>>2]=p|3;c[m+(p|4)>>2]=l|1;c[m+(l+p)>>2]=l;d=c[1830]|0;if(d){e=c[1833]|0;g=d>>>3;h=g<<1;f=7352+(h<<2)|0;j=c[1828]|0;g=1<>2]|0;if(h>>>0<(c[1832]|0)>>>0)ka();else{r=j;q=h}}else{c[1828]=j|g;r=7352+(h+2<<2)|0;q=f}c[r>>2]=e;c[q+12>>2]=e;c[e+8>>2]=q;c[e+12>>2]=f}c[1830]=l;c[1833]=b}x=m+8|0;i=L;return x|0}}}else if(a>>>0<=4294967231){a=a+11|0;p=a&-8;m=c[1829]|0;if(m){h=0-p|0;a=a>>>8;if(a)if(p>>>0>16777215)l=31;else{q=(a+1048320|0)>>>16&8;r=a<>>16&4;r=r<>>16&2;l=14-(o|q|l)+(r<>>15)|0;l=p>>>(l+7|0)&1|l<<1}else l=0;j=c[7616+(l<<2)>>2]|0;a:do if(!j){a=0;k=0}else{if((l|0)==31)k=0;else k=25-(l>>>1)|0;f=h;a=0;e=p<>2]&-8;h=g-p|0;if(h>>>0>>0)if((g|0)==(p|0)){a=j;k=j;break a}else k=j;else h=f;r=c[j+20>>2]|0;j=c[j+(e>>>31<<2)+16>>2]|0;a=(r|0)==0|(r|0)==(j|0)?a:r;if(!j)break;else{f=h;e=e<<1}}}while(0);if((a|0)==0&(k|0)==0){a=2<>>12&16;r=r>>>n;m=r>>>5&8;r=r>>>m;o=r>>>2&4;r=r>>>o;q=r>>>1&2;r=r>>>q;a=r>>>1&1;a=c[7616+((m|n|o|q|a)+(r>>>a)<<2)>>2]|0}if(!a){n=h;m=k}else while(1){r=(c[a+4>>2]&-8)-p|0;j=r>>>0>>0;h=j?r:h;k=j?a:k;j=c[a+16>>2]|0;if(j){a=j;continue}a=c[a+20>>2]|0;if(!a){n=h;m=k;break}}if((m|0)!=0?n>>>0<((c[1830]|0)-p|0)>>>0:0){k=c[1832]|0;if(m>>>0>>0)ka();o=m+p|0;if(m>>>0>=o>>>0)ka();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){b=0;break}}while(1){f=j+20|0;g=c[f>>2]|0;if(g){j=g;h=f;continue}f=j+16|0;g=c[f>>2]|0;if(!g)break;else{j=g;h=f}}if(h>>>0>>0)ka();else{c[h>>2]=0;b=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ka();j=f+12|0;if((c[j>>2]|0)!=(m|0))ka();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;b=g;break}else ka()}while(0);do if(a){j=c[m+28>>2]|0;h=7616+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=b;if(!b){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=b;else c[a+20>>2]=b;if(!b)break}h=c[1832]|0;if(b>>>0>>0)ka();c[b+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ka();else{c[b+16>>2]=j;c[j+24>>2]=b;break}while(0);j=c[m+20>>2]|0;if(j)if(j>>>0<(c[1832]|0)>>>0)ka();else{c[b+20>>2]=j;c[j+24>>2]=b;break}}while(0);b:do if(n>>>0>=16){c[m+4>>2]=p|3;c[m+(p|4)>>2]=n|1;c[m+(n+p)>>2]=n;j=n>>>3;if(n>>>0<256){g=j<<1;d=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(e>>>0>=(c[1832]|0)>>>0){t=f;u=e;break}ka()}while(0);c[t>>2]=o;c[u+12>>2]=o;c[m+(p+8)>>2]=u;c[m+(p+12)>>2]=d;break}d=n>>>8;if(d)if(n>>>0>16777215)f=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|w|f)+(x<>>15)|0;f=n>>>(f+7|0)&1|f<<1}else f=0;h=7616+(f<<2)|0;c[m+(p+28)>>2]=f;c[m+(p+20)>>2]=0;c[m+(p+16)>>2]=0;j=c[1829]|0;g=1<>2]=o;c[m+(p+24)>>2]=h;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break}j=c[h>>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;c:do if((c[j+4>>2]&-8|0)!=(n|0)){f=n<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(n|0)){v=h;break c}else{f=f<<1;j=h}}if(g>>>0<(c[1832]|0)>>>0)ka();else{c[g>>2]=o;c[m+(p+24)>>2]=j;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break b}}else v=j;while(0);b=v+8|0;d=c[b>>2]|0;x=c[1832]|0;if(v>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=o;c[b>>2]=o;c[m+(p+8)>>2]=d;c[m+(p+12)>>2]=v;c[m+(p+24)>>2]=0;break}else ka()}else{x=n+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}while(0);x=m+8|0;i=L;return x|0}}}else p=-1;while(0);k=c[1830]|0;if(k>>>0>=p>>>0){d=k-p|0;b=c[1833]|0;if(d>>>0>15){c[1833]=b+p;c[1830]=d;c[b+(p+4)>>2]=d|1;c[b+k>>2]=d;c[b+4>>2]=p|3}else{c[1830]=0;c[1833]=0;c[b+4>>2]=k|3;x=b+(k+4)|0;c[x>>2]=c[x>>2]|1}x=b+8|0;i=L;return x|0}k=c[1831]|0;if(k>>>0>p>>>0){w=k-p|0;c[1831]=w;x=c[1834]|0;c[1834]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}do if(!(c[1946]|0)){k=ua(30)|0;if(!(k+-1&k)){c[1948]=k;c[1947]=k;c[1949]=-1;c[1950]=-1;c[1951]=0;c[1939]=0;c[1946]=(ta(0)|0)&-16^1431655768;break}else ka()}while(0);l=p+48|0;g=c[1948]|0;f=p+47|0;h=g+f|0;g=0-g|0;m=h&g;if(m>>>0<=p>>>0){x=0;i=L;return x|0}a=c[1938]|0;if((a|0)!=0?(u=c[1936]|0,v=u+m|0,v>>>0<=u>>>0|v>>>0>a>>>0):0){x=0;i=L;return x|0}d:do if(!(c[1939]&4)){j=c[1834]|0;e:do if(j){a=7760|0;while(1){k=c[a>>2]|0;if(k>>>0<=j>>>0?(s=a+4|0,(k+(c[s>>2]|0)|0)>>>0>j>>>0):0)break;a=c[a+8>>2]|0;if(!a){A=181;break e}}if(a){k=h-(c[1831]|0)&g;if(k>>>0<2147483647){j=ma(k|0)|0;if((j|0)==((c[a>>2]|0)+(c[s>>2]|0)|0))A=190;else A=191}else k=0}else A=181}else A=181;while(0);do if((A|0)==181){j=ma(0)|0;if((j|0)!=(-1|0)){a=j;k=c[1947]|0;h=k+-1|0;if(!(h&a))k=m;else k=m-a+(h+a&0-k)|0;a=c[1936]|0;h=a+k|0;if(k>>>0>p>>>0&k>>>0<2147483647){v=c[1938]|0;if((v|0)!=0?h>>>0<=a>>>0|h>>>0>v>>>0:0){k=0;break}h=ma(k|0)|0;if((h|0)==(j|0))A=190;else{j=h;A=191}}else k=0}else k=0}while(0);f:do if((A|0)==190){if((j|0)!=(-1|0)){w=j;s=k;A=201;break d}}else if((A|0)==191){a=0-k|0;do if((j|0)!=(-1|0)&k>>>0<2147483647&l>>>0>k>>>0?(d=c[1948]|0,d=f-k+d&0-d,d>>>0<2147483647):0)if((ma(d|0)|0)==(-1|0)){ma(a|0)|0;k=0;break f}else{k=d+k|0;break}while(0);if((j|0)==(-1|0))k=0;else{w=j;s=k;A=201;break d}}while(0);c[1939]=c[1939]|4;A=198}else{k=0;A=198}while(0);if((((A|0)==198?m>>>0<2147483647:0)?(w=ma(m|0)|0,x=ma(0)|0,(w|0)!=(-1|0)&(x|0)!=(-1|0)&w>>>0>>0):0)?(z=x-w|0,y=z>>>0>(p+40|0)>>>0,y):0){s=y?z:k;A=201}if((A|0)==201){j=(c[1936]|0)+s|0;c[1936]=j;if(j>>>0>(c[1937]|0)>>>0)c[1937]=j;o=c[1834]|0;g:do if(o){f=7760|0;while(1){k=c[f>>2]|0;g=f+4|0;j=c[g>>2]|0;if((w|0)==(k+j|0)){A=213;break}h=c[f+8>>2]|0;if(!h)break;else f=h}if(((A|0)==213?(c[f+12>>2]&8|0)==0:0)?o>>>0>=k>>>0&o>>>0>>0:0){c[g>>2]=j+s;d=(c[1831]|0)+s|0;b=o+8|0;if(!(b&7))b=0;else b=0-b&7;x=d-b|0;c[1834]=o+b;c[1831]=x;c[o+(b+4)>>2]=x|1;c[o+(d+4)>>2]=40;c[1835]=c[1950];break}k=c[1832]|0;if(w>>>0>>0){c[1832]=w;k=w}h=w+s|0;g=7760|0;while(1){if((c[g>>2]|0)==(h|0)){A=223;break}j=c[g+8>>2]|0;if(!j)break;else g=j}if((A|0)==223?(c[g+12>>2]&8|0)==0:0){c[g>>2]=w;j=g+4|0;c[j>>2]=(c[j>>2]|0)+s;j=w+8|0;if(!(j&7))r=0;else r=0-j&7;j=w+(s+8)|0;if(!(j&7))b=0;else b=0-j&7;j=w+(b+s)|0;q=r+p|0;n=w+q|0;d=j-(w+r)-p|0;c[w+(r+4)>>2]=p|3;h:do if((j|0)!=(o|0)){if((j|0)==(c[1833]|0)){x=(c[1830]|0)+d|0;c[1830]=x;c[1833]=n;c[w+(q+4)>>2]=x|1;c[w+(x+q)>>2]=x;break}l=s+4|0;h=c[w+(l+b)>>2]|0;if((h&3|0)==1){m=h&-8;e=h>>>3;i:do if(h>>>0>=256){a=c[w+((b|24)+s)>>2]|0;g=c[w+(s+12+b)>>2]|0;do if((g|0)==(j|0)){g=b|16;f=w+(l+g)|0;h=c[f>>2]|0;if(!h){g=w+(g+s)|0;h=c[g>>2]|0;if(!h){H=0;break}}else g=f;while(1){e=h+20|0;f=c[e>>2]|0;if(f){h=f;g=e;continue}e=h+16|0;f=c[e>>2]|0;if(!f)break;else{h=f;g=e}}if(g>>>0>>0)ka();else{c[g>>2]=0;H=h;break}}else{f=c[w+((b|8)+s)>>2]|0;if(f>>>0>>0)ka();k=f+12|0;if((c[k>>2]|0)!=(j|0))ka();h=g+8|0;if((c[h>>2]|0)==(j|0)){c[k>>2]=g;c[h>>2]=f;H=g;break}else ka()}while(0);if(!a)break;k=c[w+(s+28+b)>>2]|0;h=7616+(k<<2)|0;do if((j|0)!=(c[h>>2]|0)){if(a>>>0<(c[1832]|0)>>>0)ka();k=a+16|0;if((c[k>>2]|0)==(j|0))c[k>>2]=H;else c[a+20>>2]=H;if(!H)break i}else{c[h>>2]=H;if(H)break;c[1829]=c[1829]&~(1<>>0>>0)ka();c[H+24>>2]=a;j=b|16;k=c[w+(j+s)>>2]|0;do if(k)if(k>>>0>>0)ka();else{c[H+16>>2]=k;c[k+24>>2]=H;break}while(0);j=c[w+(l+j)>>2]|0;if(!j)break;if(j>>>0<(c[1832]|0)>>>0)ka();else{c[H+20>>2]=j;c[j+24>>2]=H;break}}else{g=c[w+((b|8)+s)>>2]|0;f=c[w+(s+12+b)>>2]|0;h=7352+(e<<1<<2)|0;do if((g|0)!=(h|0)){if(g>>>0>>0)ka();if((c[g+12>>2]|0)==(j|0))break;ka()}while(0);if((f|0)==(g|0)){c[1828]=c[1828]&~(1<>>0>>0)ka();k=f+8|0;if((c[k>>2]|0)==(j|0)){D=k;break}ka()}while(0);c[g+12>>2]=f;c[D>>2]=g}while(0);j=w+((m|b)+s)|0;k=m+d|0}else k=d;j=j+4|0;c[j>>2]=c[j>>2]&-2;c[w+(q+4)>>2]=k|1;c[w+(k+q)>>2]=k;j=k>>>3;if(k>>>0<256){g=j<<1;f=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(h>>>0>=(c[1832]|0)>>>0){I=j;J=h;break}ka()}while(0);c[I>>2]=n;c[J+12>>2]=n;c[w+(q+8)>>2]=J;c[w+(q+12)>>2]=f;break}d=k>>>8;do if(!d)f=0;else{if(k>>>0>16777215){f=31;break}v=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|v|f)+(x<>>15)|0;f=k>>>(f+7|0)&1|f<<1}while(0);h=7616+(f<<2)|0;c[w+(q+28)>>2]=f;c[w+(q+20)>>2]=0;c[w+(q+16)>>2]=0;j=c[1829]|0;g=1<>2]=n;c[w+(q+24)>>2]=h;c[w+(q+12)>>2]=n;c[w+(q+8)>>2]=n;break}j=c[h>>2]|0;if((f|0)==31)h=0;else h=25-(f>>>1)|0;j:do if((c[j+4>>2]&-8|0)!=(k|0)){f=k<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(k|0)){K=h;break j}else{f=f<<1;j=h}}if(g>>>0<(c[1832]|0)>>>0)ka();else{c[g>>2]=n;c[w+(q+24)>>2]=j;c[w+(q+12)>>2]=n;c[w+(q+8)>>2]=n;break h}}else K=j;while(0);b=K+8|0;d=c[b>>2]|0;x=c[1832]|0;if(K>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=n;c[b>>2]=n;c[w+(q+8)>>2]=d;c[w+(q+12)>>2]=K;c[w+(q+24)>>2]=0;break}else ka()}else{x=(c[1831]|0)+d|0;c[1831]=x;c[1834]=n;c[w+(q+4)>>2]=x|1}while(0);x=w+(r|8)|0;i=L;return x|0}j=7760|0;while(1){h=c[j>>2]|0;if(h>>>0<=o>>>0?(B=c[j+4>>2]|0,C=h+B|0,C>>>0>o>>>0):0)break;j=c[j+8>>2]|0}j=h+(B+-39)|0;if(!(j&7))j=0;else j=0-j&7;g=h+(B+-47+j)|0;g=g>>>0<(o+16|0)>>>0?o:g;h=g+8|0;j=w+8|0;if(!(j&7))j=0;else j=0-j&7;f=s+-40-j|0;c[1834]=w+j;c[1831]=f;c[w+(j+4)>>2]=f|1;c[w+(s+-36)>>2]=40;c[1835]=c[1950];c[g+4>>2]=27;c[h+0>>2]=c[1940];c[h+4>>2]=c[1941];c[h+8>>2]=c[1942];c[h+12>>2]=c[1943];c[1940]=w;c[1941]=s;c[1943]=0;c[1942]=h;f=g+28|0;c[f>>2]=7;if((g+32|0)>>>0>>0)do{x=f;f=f+4|0;c[f>>2]=7}while((x+8|0)>>>0>>0);if((g|0)!=(o|0)){k=g-o|0;j=o+(k+4)|0;c[j>>2]=c[j>>2]&-2;c[o+4>>2]=k|1;c[o+k>>2]=k;j=k>>>3;if(k>>>0<256){g=j<<1;f=7352+(g<<2)|0;h=c[1828]|0;j=1<>2]|0;if(b>>>0>=(c[1832]|0)>>>0){E=d;F=b;break}ka()}while(0);c[E>>2]=o;c[F+12>>2]=o;c[o+8>>2]=F;c[o+12>>2]=f;break}d=k>>>8;if(d)if(k>>>0>16777215)g=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;g=14-(v|w|g)+(x<>>15)|0;g=k>>>(g+7|0)&1|g<<1}else g=0;h=7616+(g<<2)|0;c[o+28>>2]=g;c[o+20>>2]=0;c[o+16>>2]=0;e=c[1829]|0;j=1<>2]=o;c[o+24>>2]=h;c[o+12>>2]=o;c[o+8>>2]=o;break}e=c[h>>2]|0;if((g|0)==31)d=0;else d=25-(g>>>1)|0;k:do if((c[e+4>>2]&-8|0)!=(k|0)){j=k<>>31<<2)+16|0;d=c[h>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(k|0)){G=d;break k}else{j=j<<1;e=d}}if(h>>>0<(c[1832]|0)>>>0)ka();else{c[h>>2]=o;c[o+24>>2]=e;c[o+12>>2]=o;c[o+8>>2]=o;break g}}else G=e;while(0);b=G+8|0;d=c[b>>2]|0;x=c[1832]|0;if(G>>>0>=x>>>0&d>>>0>=x>>>0){c[d+12>>2]=o;c[b>>2]=o;c[o+8>>2]=d;c[o+12>>2]=G;c[o+24>>2]=0;break}else ka()}}else{x=c[1832]|0;if((x|0)==0|w>>>0>>0)c[1832]=w;c[1940]=w;c[1941]=s;c[1943]=0;c[1837]=c[1946];c[1836]=-1;b=0;do{x=b<<1;v=7352+(x<<2)|0;c[7352+(x+3<<2)>>2]=v;c[7352+(x+2<<2)>>2]=v;b=b+1|0}while((b|0)!=32);b=w+8|0;if(!(b&7))b=0;else b=0-b&7;x=s+-40-b|0;c[1834]=w+b;c[1831]=x;c[w+(b+4)>>2]=x|1;c[w+(s+-36)>>2]=40;c[1835]=c[1950]}while(0);b=c[1831]|0;if(b>>>0>p>>>0){w=b-p|0;c[1831]=w;x=c[1834]|0;c[1834]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}}c[(va()|0)>>2]=12;x=0;i=L;return x|0}function kd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=i;if(!a){i=w;return}f=a+-8|0;h=c[1832]|0;if(f>>>0>>0)ka();g=c[a+-4>>2]|0;e=g&3;if((e|0)==1)ka();q=g&-8;r=a+(q+-8)|0;do if(!(g&1)){g=c[f>>2]|0;if(!e){i=w;return}j=-8-g|0;m=a+j|0;n=g+q|0;if(m>>>0>>0)ka();if((m|0)==(c[1833]|0)){f=a+(q+-4)|0;g=c[f>>2]|0;if((g&3|0)!=3){v=m;l=n;break}c[1830]=n;c[f>>2]=g&-2;c[a+(j+4)>>2]=n|1;c[r>>2]=n;i=w;return}d=g>>>3;if(g>>>0<256){e=c[a+(j+8)>>2]|0;f=c[a+(j+12)>>2]|0;g=7352+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0>>0)ka();if((c[e+12>>2]|0)!=(m|0))ka()}if((f|0)==(e|0)){c[1828]=c[1828]&~(1<>>0>>0)ka();g=f+8|0;if((c[g>>2]|0)==(m|0))b=g;else ka()}else b=f+8|0;c[e+12>>2]=f;c[b>>2]=e;v=m;l=n;break}b=c[a+(j+24)>>2]|0;e=c[a+(j+12)>>2]|0;do if((e|0)==(m|0)){f=a+(j+20)|0;g=c[f>>2]|0;if(!g){f=a+(j+16)|0;g=c[f>>2]|0;if(!g){k=0;break}}while(1){d=g+20|0;e=c[d>>2]|0;if(e){g=e;f=d;continue}d=g+16|0;e=c[d>>2]|0;if(!e)break;else{g=e;f=d}}if(f>>>0>>0)ka();else{c[f>>2]=0;k=g;break}}else{d=c[a+(j+8)>>2]|0;if(d>>>0>>0)ka();g=d+12|0;if((c[g>>2]|0)!=(m|0))ka();f=e+8|0;if((c[f>>2]|0)==(m|0)){c[g>>2]=e;c[f>>2]=d;k=e;break}else ka()}while(0);if(b){g=c[a+(j+28)>>2]|0;f=7616+(g<<2)|0;if((m|0)==(c[f>>2]|0)){c[f>>2]=k;if(!k){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();g=b+16|0;if((c[g>>2]|0)==(m|0))c[g>>2]=k;else c[b+20>>2]=k;if(!k){v=m;l=n;break}}f=c[1832]|0;if(k>>>0>>0)ka();c[k+24>>2]=b;g=c[a+(j+16)>>2]|0;do if(g)if(g>>>0>>0)ka();else{c[k+16>>2]=g;c[g+24>>2]=k;break}while(0);g=c[a+(j+20)>>2]|0;if(g)if(g>>>0<(c[1832]|0)>>>0)ka();else{c[k+20>>2]=g;c[g+24>>2]=k;v=m;l=n;break}else{v=m;l=n}}else{v=m;l=n}}else{v=f;l=q}while(0);if(v>>>0>=r>>>0)ka();g=a+(q+-4)|0;f=c[g>>2]|0;if(!(f&1))ka();if(!(f&2)){if((r|0)==(c[1834]|0)){m=(c[1831]|0)+l|0;c[1831]=m;c[1834]=v;c[v+4>>2]=m|1;if((v|0)!=(c[1833]|0)){i=w;return}c[1833]=0;c[1830]=0;i=w;return}if((r|0)==(c[1833]|0)){m=(c[1830]|0)+l|0;c[1830]=m;c[1833]=v;c[v+4>>2]=m|1;c[v+m>>2]=m;i=w;return}h=(f&-8)+l|0;d=f>>>3;do if(f>>>0>=256){b=c[a+(q+16)>>2]|0;g=c[a+(q|4)>>2]|0;do if((g|0)==(r|0)){f=a+(q+12)|0;g=c[f>>2]|0;if(!g){f=a+(q+8)|0;g=c[f>>2]|0;if(!g){p=0;break}}while(1){d=g+20|0;e=c[d>>2]|0;if(e){g=e;f=d;continue}d=g+16|0;e=c[d>>2]|0;if(!e)break;else{g=e;f=d}}if(f>>>0<(c[1832]|0)>>>0)ka();else{c[f>>2]=0;p=g;break}}else{f=c[a+q>>2]|0;if(f>>>0<(c[1832]|0)>>>0)ka();e=f+12|0;if((c[e>>2]|0)!=(r|0))ka();d=g+8|0;if((c[d>>2]|0)==(r|0)){c[e>>2]=g;c[d>>2]=f;p=g;break}else ka()}while(0);if(b){g=c[a+(q+20)>>2]|0;f=7616+(g<<2)|0;if((r|0)==(c[f>>2]|0)){c[f>>2]=p;if(!p){c[1829]=c[1829]&~(1<>>0<(c[1832]|0)>>>0)ka();g=b+16|0;if((c[g>>2]|0)==(r|0))c[g>>2]=p;else c[b+20>>2]=p;if(!p)break}g=c[1832]|0;if(p>>>0>>0)ka();c[p+24>>2]=b;f=c[a+(q+8)>>2]|0;do if(f)if(f>>>0>>0)ka();else{c[p+16>>2]=f;c[f+24>>2]=p;break}while(0);d=c[a+(q+12)>>2]|0;if(d)if(d>>>0<(c[1832]|0)>>>0)ka();else{c[p+20>>2]=d;c[d+24>>2]=p;break}}}else{e=c[a+q>>2]|0;f=c[a+(q|4)>>2]|0;g=7352+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0<(c[1832]|0)>>>0)ka();if((c[e+12>>2]|0)!=(r|0))ka()}if((f|0)==(e|0)){c[1828]=c[1828]&~(1<>>0<(c[1832]|0)>>>0)ka();g=f+8|0;if((c[g>>2]|0)==(r|0))o=g;else ka()}else o=f+8|0;c[e+12>>2]=f;c[o>>2]=e}while(0);c[v+4>>2]=h|1;c[v+h>>2]=h;if((v|0)==(c[1833]|0)){c[1830]=h;i=w;return}else g=h}else{c[g>>2]=f&-2;c[v+4>>2]=l|1;c[v+l>>2]=l;g=l}e=g>>>3;if(g>>>0<256){f=e<<1;g=7352+(f<<2)|0;d=c[1828]|0;e=1<>2]|0;if(b>>>0<(c[1832]|0)>>>0)ka();else{s=d;t=b}}else{c[1828]=d|e;s=7352+(f+2<<2)|0;t=g}c[s>>2]=v;c[t+12>>2]=v;c[v+8>>2]=t;c[v+12>>2]=g;i=w;return}d=g>>>8;if(d)if(g>>>0>16777215)f=31;else{l=(d+1048320|0)>>>16&8;m=d<>>16&4;m=m<>>16&2;f=14-(k|l|f)+(m<>>15)|0;f=g>>>(f+7|0)&1|f<<1}else f=0;b=7616+(f<<2)|0;c[v+28>>2]=f;c[v+20>>2]=0;c[v+16>>2]=0;d=c[1829]|0;e=1<>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;b:do if((c[b+4>>2]&-8|0)!=(g|0)){f=g<>>31<<2)+16|0;d=c[e>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(g|0)){u=d;break b}else{f=f<<1;b=d}}if(e>>>0<(c[1832]|0)>>>0)ka();else{c[e>>2]=v;c[v+24>>2]=b;c[v+12>>2]=v;c[v+8>>2]=v;break a}}else u=b;while(0);d=u+8|0;b=c[d>>2]|0;m=c[1832]|0;if(u>>>0>=m>>>0&b>>>0>=m>>>0){c[b+12>>2]=v;c[d>>2]=v;c[v+8>>2]=b;c[v+12>>2]=u;c[v+24>>2]=0;break}else ka()}else{c[1829]=d|e;c[b>>2]=v;c[v+24>>2]=b;c[v+12>>2]=v;c[v+8>>2]=v}while(0);m=(c[1836]|0)+-1|0;c[1836]=m;if(!m)b=7768|0;else{i=w;return}while(1){b=c[b>>2]|0;if(!b)break;else b=b+8|0}c[1836]=-1;i=w;return}function ld(){}function md(b){b=b|0;var c=0;c=b;while(a[c>>0]|0)c=c+1|0;return c-b|0}function nd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;h=b&3;i=d|d<<8|d<<16|d<<24;g=f&~3;if(h){h=b+4-h|0;while((b|0)<(h|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(g|0)){c[b>>2]=i;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function od(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return pa(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function pd(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;xa[a&3](b|0,c|0,d|0,e|0,f|0)}function qd(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;_(0)} + +// EMSCRIPTEN_END_FUNCS +var xa=[qd,fc,ec,qd];return{_strlen:md,_free:kd,_broadwayGetMajorVersion:dd,_get_h264bsdClip:Lb,_broadwayExit:cd,_memset:nd,_broadwayCreateStream:Zc,_malloc:jd,_memcpy:od,_broadwayGetMinorVersion:ed,_broadwayPlayStream:$c,_broadwaySetStreamLength:_c,_broadwayInit:ad,runPostSets:ld,stackAlloc:ya,stackSave:za,stackRestore:Aa,setThrew:Ba,setTempRet0:Ea,getTempRet0:Fa,dynCall_viiiii:pd}}) + + +// EMSCRIPTEN_END_ASM +(p.Xc,p.Yc,Q),Bb=p._strlen=$._strlen,Ea=p._free=$._free;p._broadwayGetMajorVersion=$._broadwayGetMajorVersion;p._get_h264bsdClip=$._get_h264bsdClip;p._broadwayExit=$._broadwayExit;var Gb=p._memset=$._memset;p._broadwayCreateStream=$._broadwayCreateStream;var Ca=p._malloc=$._malloc,gc=p._memcpy=$._memcpy; +p._broadwayGetMinorVersion=$._broadwayGetMinorVersion;p._broadwayPlayStream=$._broadwayPlayStream;p._broadwaySetStreamLength=$._broadwaySetStreamLength;p._broadwayInit=$._broadwayInit;p.runPostSets=$.runPostSets;p.dynCall_viiiii=$.dynCall_viiiii;z.pb=$.stackAlloc;z.Tb=$.stackSave;z.Sb=$.stackRestore;z.Yd=$.setTempRet0;z.xd=$.getTempRet0; +if(T)if("function"===typeof p.locateFile?T=p.locateFile(T):p.memoryInitializerPrefixURL&&(T=p.memoryInitializerPrefixURL+T),t||da){var hc=p.readBinary(T);N.set(hc,Ia)}else Ya(),yb(T,function(a){N.set(a,Ia);Za()},function(){d("could not load memory initializer "+T)});function ia(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}ia.prototype=Error();var ic,jc=k,Xa=function kc(){!p.calledRun&&lc&&mc();p.calledRun||(Xa=kc)}; +p.callMain=p.ag=function(a){function b(){for(var a=0;3>a;a++)e.push(0)}w(0==S,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");w(0==Oa.length,"cannot call main when preRun functions remain to be called");a=a||[];Sa||(Sa=i,Na(R));var c=a.length+1,e=[M(Va(p.thisProgram),"i8",0)];b();for(var f=0;f y ? y : z); + } + + function OptimizedGetBoundaryStrengthsA($mb, $bS) { + var $totalCoeff = $mb + 28; + + var tc0 = HEAP16[$totalCoeff + 0 >> 1]; + var tc1 = HEAP16[$totalCoeff + 2 >> 1]; + var tc2 = HEAP16[$totalCoeff + 4 >> 1]; + var tc3 = HEAP16[$totalCoeff + 6 >> 1]; + var tc4 = HEAP16[$totalCoeff + 8 >> 1]; + var tc5 = HEAP16[$totalCoeff + 10 >> 1]; + var tc6 = HEAP16[$totalCoeff + 12 >> 1]; + var tc7 = HEAP16[$totalCoeff + 14 >> 1]; + var tc8 = HEAP16[$totalCoeff + 16 >> 1]; + var tc9 = HEAP16[$totalCoeff + 18 >> 1]; + var tc10 = HEAP16[$totalCoeff + 20 >> 1]; + var tc11 = HEAP16[$totalCoeff + 22 >> 1]; + var tc12 = HEAP16[$totalCoeff + 24 >> 1]; + var tc13 = HEAP16[$totalCoeff + 26 >> 1]; + var tc14 = HEAP16[$totalCoeff + 28 >> 1]; + var tc15 = HEAP16[$totalCoeff + 30 >> 1]; + + HEAP32[$bS + 32 >> 2] = tc2 || tc0 ? 2 : 0; + HEAP32[$bS + 40 >> 2] = tc3 || tc1 ? 2 : 0; + HEAP32[$bS + 48 >> 2] = tc6 || tc4 ? 2 : 0; + HEAP32[$bS + 56 >> 2] = tc7 || tc5 ? 2 : 0; + HEAP32[$bS + 64 >> 2] = tc8 || tc2 ? 2 : 0; + HEAP32[$bS + 72 >> 2] = tc9 || tc3 ? 2 : 0; + HEAP32[$bS + 80 >> 2] = tc12 || tc6 ? 2 : 0; + HEAP32[$bS + 88 >> 2] = tc13 || tc7 ? 2 : 0; + HEAP32[$bS + 96 >> 2] = tc10 || tc8 ? 2 : 0; + HEAP32[$bS + 104 >> 2] = tc11 || tc9 ? 2 : 0; + HEAP32[$bS + 112 >> 2] = tc14 || tc12 ? 2 : 0; + HEAP32[$bS + 120 >> 2] = tc15 || tc13 ? 2 : 0; + + HEAP32[$bS + 12 >> 2] = tc1 || tc0 ? 2 : 0; + HEAP32[$bS + 20 >> 2] = tc4 || tc1 ? 2 : 0; + HEAP32[$bS + 28 >> 2] = tc5 || tc4 ? 2 : 0; + HEAP32[$bS + 44 >> 2] = tc3 || tc2 ? 2 : 0; + HEAP32[$bS + 52 >> 2] = tc6 || tc3 ? 2 : 0; + HEAP32[$bS + 60 >> 2] = tc7 || tc6 ? 2 : 0; + HEAP32[$bS + 76 >> 2] = tc9 || tc8 ? 2 : 0; + HEAP32[$bS + 84 >> 2] = tc12 || tc9 ? 2 : 0; + HEAP32[$bS + 92 >> 2] = tc13 || tc12 ? 2 : 0; + HEAP32[$bS + 108 >> 2] = tc11 || tc10 ? 2 : 0; + HEAP32[$bS + 116 >> 2] = tc14 || tc11 ? 2 : 0; + HEAP32[$bS + 124 >> 2] = tc15 || tc14 ? 2 : 0; + } + + function OptimizedFilterVerLumaEdge ($data, bS, $thresholds, imageWidth) { + var delta, tc, tmp; + var p0, q0, p1, q1, p2, q2; + var tmpFlag; + var $clp = _h264bsdClip + 512; + var alpha = HEAP32[$thresholds + 4 >> 2]; + var beta = HEAP32[$thresholds + 8 >> 2]; + var val; + + if (bS < 4) { + tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255; + for (var i = 4; i > 0; i--) { + p1 = HEAPU8[$data + -2] & 255; + p0 = HEAPU8[$data + -1] & 255; + q0 = HEAPU8[$data] & 255; + q1 = HEAPU8[$data + 1] & 255; + if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) { + p2 = HEAPU8[$data - 3] & 255; + if (Math.abs(p2 - p0) < beta) { + val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; + HEAP8[$data - 2] = p1 + clip(-tc, tc, val); + tmp++; + } + + q2 = HEAPU8[$data + 2] & 255; + if (Math.abs(q2 - q0) < beta) { + val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; + HEAP8[$data + 1] = (q1 + clip(-tc, tc, val)); + tmp++; + } + + val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); + delta = clip(-tmp, tmp, val); + + p0 = HEAPU8[$clp + (p0 + delta)] & 255; + q0 = HEAPU8[$clp + (q0 - delta)] & 255; + tmp = tc; + HEAP8[$data - 1] = p0; + HEAP8[$data] = q0; + + $data += imageWidth; + } + } + } else { + OriginalFilterVerLumaEdge($data, bS, $thresholds, imageWidth); + } + } + + /** + * Filter all four successive horizontal 4-pixel luma edges. This can be done when bS is equal to all four edges. + */ + function OptimizedFilterHorLuma ($data, bS, $thresholds, imageWidth) { + var delta, tc, tmp; + var p0, q0, p1, q1, p2, q2; + var tmpFlag; + var $clp = _h264bsdClip + 512; + var alpha = HEAP32[$thresholds + 4 >> 2]; + var beta = HEAP32[$thresholds + 8 >> 2]; + var val; + + if (bS < 4) { + tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255; + for (var i = 16; i > 0; i--) { + p1 = HEAPU8[$data + (-imageWidth << 1)] & 255; + p0 = HEAPU8[$data + -imageWidth] & 255; + q0 = HEAPU8[$data] & 255; + q1 = HEAPU8[$data + imageWidth] & 255; + + if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) { + p2 = HEAPU8[$data + (-imageWidth * 3)] & 255; + if (Math.abs(p2 - p0) < beta) { + val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1; + HEAP8[$data + (-imageWidth << 1)] = p1 + clip(-tc, tc, val); + tmp++; + } + + q2 = HEAPU8[$data + (imageWidth << 2)] & 255; + if (Math.abs(q2 - q0) < beta) { + val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1; + HEAP8[$data + imageWidth] = (q1 + clip(-tc, tc, val)); + tmp++; + } + + val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3); + delta = clip(-tmp, tmp, val); + + p0 = HEAPU8[$clp + (p0 + delta)] & 255; + q0 = HEAPU8[$clp + (q0 - delta)] & 255; + tmp = tc; + HEAP8[$data - imageWidth] = p0; + HEAP8[$data] = q0; + + $data ++; + } + } + } else { + OriginalFilterHorLuma($data, bS, $thresholds, imageWidth); + } + } + }; + + + Broadway.prototype = { + configure: function (config) { + // patchOptimizations(config, patches); + console.info("Broadway Configured: " + JSON.stringify(config)); + } + + }; + + + + + /* + + asm.js implementation of a yuv to rgb convertor + provided by @soliton4 + + based on + http://www.wordsaretoys.com/2013/10/18/making-yuv-conversion-a-little-faster/ + + */ + + + // factory to create asm.js yuv -> rgb convertor for a given resolution + var asmInstances = {}; + var getAsm = function(parWidth, parHeight){ + var idStr = "" + parWidth + "x" + parHeight; + if (asmInstances[idStr]){ + return asmInstances[idStr]; + }; + + var lumaSize = parWidth * parHeight; + var chromaSize = (lumaSize|0) >> 2; + + var inpSize = lumaSize + chromaSize + chromaSize; + var outSize = parWidth * parHeight * 4; + var cacheSize = Math.pow(2, 24) * 4; + var size = inpSize + outSize + cacheSize; + + var chunkSize = Math.pow(2, 24); + var heapSize = chunkSize; + while (heapSize < size){ + heapSize += chunkSize; + }; + var heap = new ArrayBuffer(heapSize); + + var res = asmFactory(global, {}, heap); + res.init(parWidth, parHeight); + asmInstances[idStr] = res; + + res.heap = heap; + res.out = new Uint8Array(heap, 0, outSize); + res.inp = new Uint8Array(heap, outSize, inpSize); + res.outSize = outSize; + + return res; + }; + + + function asmFactory(stdlib, foreign, heap) { + "use asm"; + + var imul = stdlib.Math.imul; + var min = stdlib.Math.min; + var max = stdlib.Math.max; + var pow = stdlib.Math.pow; + var out = new stdlib.Uint8Array(heap); + var out32 = new stdlib.Uint32Array(heap); + var inp = new stdlib.Uint8Array(heap); + var mem = new stdlib.Uint8Array(heap); + var mem32 = new stdlib.Uint32Array(heap); + + // for double algo + /*var vt = 1.370705; + var gt = 0.698001; + var gt2 = 0.337633; + var bt = 1.732446;*/ + + var width = 0; + var height = 0; + var lumaSize = 0; + var chromaSize = 0; + var inpSize = 0; + var outSize = 0; + + var inpStart = 0; + var outStart = 0; + + var widthFour = 0; + + var cacheStart = 0; + + + function init(parWidth, parHeight){ + parWidth = parWidth|0; + parHeight = parHeight|0; + + var i = 0; + var s = 0; + + width = parWidth; + widthFour = imul(parWidth, 4)|0; + height = parHeight; + lumaSize = imul(width|0, height|0)|0; + chromaSize = (lumaSize|0) >> 2; + outSize = imul(imul(width, height)|0, 4)|0; + inpSize = ((lumaSize + chromaSize)|0 + chromaSize)|0; + + outStart = 0; + inpStart = (outStart + outSize)|0; + cacheStart = (inpStart + inpSize)|0; + + // initializing memory (to be on the safe side) + s = ~~(+pow(+2, +24)); + s = imul(s, 4)|0; + + for (i = 0|0; ((i|0) < (s|0))|0; i = (i + 4)|0){ + mem32[((cacheStart + i)|0) >> 2] = 0; + }; + }; + + function doit(){ + var ystart = 0; + var ustart = 0; + var vstart = 0; + + var y = 0; + var yn = 0; + var u = 0; + var v = 0; + + var o = 0; + + var line = 0; + var col = 0; + + var usave = 0; + var vsave = 0; + + var ostart = 0; + var cacheAdr = 0; + + ostart = outStart|0; + + ystart = inpStart|0; + ustart = (ystart + lumaSize|0)|0; + vstart = (ustart + chromaSize)|0; + + for (line = 0; (line|0) < (height|0); line = (line + 2)|0){ + usave = ustart; + vsave = vstart; + for (col = 0; (col|0) < (width|0); col = (col + 2)|0){ + y = inp[ystart >> 0]|0; + yn = inp[((ystart + width)|0) >> 0]|0; + + u = inp[ustart >> 0]|0; + v = inp[vstart >> 0]|0; + + cacheAdr = (((((y << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(y,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[ostart >> 2] = o; + + cacheAdr = (((((yn << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(yn,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[((ostart + widthFour)|0) >> 2] = o; + + //yuv2rgb5(y, u, v, ostart); + //yuv2rgb5(yn, u, v, (ostart + widthFour)|0); + ostart = (ostart + 4)|0; + + // next step only for y. u and v stay the same + ystart = (ystart + 1)|0; + y = inp[ystart >> 0]|0; + yn = inp[((ystart + width)|0) >> 0]|0; + + //yuv2rgb5(y, u, v, ostart); + cacheAdr = (((((y << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(y,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[ostart >> 2] = o; + + //yuv2rgb5(yn, u, v, (ostart + widthFour)|0); + cacheAdr = (((((yn << 16)|0) + ((u << 8)|0))|0) + v)|0; + o = mem32[((cacheStart + cacheAdr)|0) >> 2]|0; + if (o){}else{ + o = yuv2rgbcalc(yn,u,v)|0; + mem32[((cacheStart + cacheAdr)|0) >> 2] = o|0; + }; + mem32[((ostart + widthFour)|0) >> 2] = o; + ostart = (ostart + 4)|0; + + //all positions inc 1 + + ystart = (ystart + 1)|0; + ustart = (ustart + 1)|0; + vstart = (vstart + 1)|0; + }; + ostart = (ostart + widthFour)|0; + ystart = (ystart + width)|0; + + }; + + }; + + function yuv2rgbcalc(y, u, v){ + y = y|0; + u = u|0; + v = v|0; + + var r = 0; + var g = 0; + var b = 0; + + var o = 0; + + var a0 = 0; + var a1 = 0; + var a2 = 0; + var a3 = 0; + var a4 = 0; + + a0 = imul(1192, (y - 16)|0)|0; + a1 = imul(1634, (v - 128)|0)|0; + a2 = imul(832, (v - 128)|0)|0; + a3 = imul(400, (u - 128)|0)|0; + a4 = imul(2066, (u - 128)|0)|0; + + r = (((a0 + a1)|0) >> 10)|0; + g = (((((a0 - a2)|0) - a3)|0) >> 10)|0; + b = (((a0 + a4)|0) >> 10)|0; + + if ((((r & 255)|0) != (r|0))|0){ + r = min(255, max(0, r|0)|0)|0; + }; + if ((((g & 255)|0) != (g|0))|0){ + g = min(255, max(0, g|0)|0)|0; + }; + if ((((b & 255)|0) != (b|0))|0){ + b = min(255, max(0, b|0)|0)|0; + }; + + o = 255; + o = (o << 8)|0; + o = (o + b)|0; + o = (o << 8)|0; + o = (o + g)|0; + o = (o << 8)|0; + o = (o + r)|0; + + return o|0; + + }; + + + + return { + init: init, + doit: doit + }; + }; + + + /* + potential worker initialization + + */ + + + if (typeof self != "undefined"){ + var isWorker = false; + var decoder; + var reuseMemory = false; + + var memAr = []; + var getMem = function(length){ + if (memAr.length){ + var u = memAr.shift(); + while (u && u.byteLength !== length){ + u = memAr.shift(); + }; + if (u){ + return u; + }; + }; + return new ArrayBuffer(length); + }; + + self.addEventListener('message', function(e) { + + if (isWorker){ + if (reuseMemory){ + if (e.data.reuse){ + memAr.push(e.data.reuse); + }; + }; + if (e.data.buf){ + decoder.decode(new Uint8Array(e.data.buf, e.data.offset || 0, e.data.length), e.data.info); + }; + + }else{ + if (e.data && e.data.type === "Broadway.js - Worker init"){ + isWorker = true; + decoder = new Broadway(e.data.options); + + if (e.data.options.reuseMemory){ + reuseMemory = true; + decoder.onPictureDecoded = function (buffer, width, height, infos) { + + //var buf = getMem(); + + // buffer needs to be copied because we give up ownership + var copyU8 = new Uint8Array(getMem(buffer.length)); + copyU8.set( buffer, 0, buffer.length ); + + postMessage({ + buf: copyU8.buffer, + length: buffer.length, + width: width, + height: height, + infos: infos + }, [copyU8.buffer]); // 2nd parameter is used to indicate transfer of ownership + + }; + + }else{ + decoder.onPictureDecoded = function (buffer, width, height, infos) { + if (buffer) { + buffer = new Uint8Array(buffer); + }; + + // buffer needs to be copied because we give up ownership + var copyU8 = new Uint8Array(buffer.length); + copyU8.set( buffer, 0, buffer.length ); + + postMessage({ + buf: copyU8.buffer, + length: buffer.length, + width: width, + height: height, + infos: infos + }, [copyU8.buffer]); // 2nd parameter is used to indicate transfer of ownership + + }; + }; + postMessage({ consoleLog: "broadway worker initialized" }); + }; + }; + + + }, false); + }; + + Broadway.nowValue = nowValue; + + return Broadway; + + })(); + + +})); + + +}).call(this,"/dvp\\node_modules\\h264-live-player\\vendor\\broadway") +},{}],5:[function(require,module,exports){ +"use strict"; +var assert = require('../utils/assert'); + + +function Program(gl) { + this.gl = gl; + this.program = this.gl.createProgram(); +} + +Program.prototype = { + attach: function (shader) { + this.gl.attachShader(this.program, shader.shader); + }, + link: function () { + this.gl.linkProgram(this.program); + // If creating the shader program failed, alert. + assert(this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS), + "Unable to initialize the shader program."); + }, + use: function () { + this.gl.useProgram(this.program); + }, + getAttributeLocation: function(name) { + return this.gl.getAttribLocation(this.program, name); + }, + setMatrixUniform: function(name, array) { + var uniform = this.gl.getUniformLocation(this.program, name); + this.gl.uniformMatrix4fv(uniform, false, array); + } +}; +module.exports = Program; + + +},{"../utils/assert":20}],6:[function(require,module,exports){ +"use strict"; + +var assert = require('../utils/assert'); + +/** + * Represents a WebGL shader script. + */ + +function Script() {} + +Script.createFromElementId = function(id) { + var script = document.getElementById(id); + + // Didn't find an element with the specified ID, abort. + assert(script , "Could not find shader with ID: " + id); + + // Walk through the source element's children, building the shader source string. + var source = ""; + var currentChild = script .firstChild; + while(currentChild) { + if (currentChild.nodeType == 3) { + source += currentChild.textContent; + } + currentChild = currentChild.nextSibling; + } + + var res = new Scriptor(); + res.type = script.type; + res.source = source; + return res; +}; + +Script.createFromSource = function(type, source) { + var res = new Script(); + res.type = type; + res.source = source; + return res; +} + + +module.exports = Script; +},{"../utils/assert":20}],7:[function(require,module,exports){ +"use strict"; + +var error = require('../utils/error'); + +/** + * Represents a WebGL shader object and provides a mechanism to load shaders from HTML + * script tags. + */ + + +function Shader(gl, script) { + + // Now figure out what type of shader script we have, based on its MIME type. + if (script.type == "x-shader/x-fragment") { + this.shader = gl.createShader(gl.FRAGMENT_SHADER); + } else if (script.type == "x-shader/x-vertex") { + this.shader = gl.createShader(gl.VERTEX_SHADER); + } else { + error("Unknown shader type: " + script.type); + return; + } + + // Send the source to the shader object. + gl.shaderSource(this.shader, script.source); + + // Compile the shader program. + gl.compileShader(this.shader); + + // See if it compiled successfully. + if (!gl.getShaderParameter(this.shader, gl.COMPILE_STATUS)) { + error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(this.shader)); + return; + } +} +module.exports = Shader; + + + + +},{"../utils/error":21}],8:[function(require,module,exports){ +"use strict"; + +var assert = require('../utils/assert'); + +/** + * Represents a WebGL texture object. + */ + +function Texture(gl, size, format) { + this.gl = gl; + this.size = size; + this.texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + this.format = format ? format : gl.LUMINANCE; + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, size.w, size.h, 0, this.format, gl.UNSIGNED_BYTE, null); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); +} + +var textureIDs = null; +Texture.prototype = { + fill: function(textureData, useTexSubImage2D) { + var gl = this.gl; + assert(textureData.length >= this.size.w * this.size.h, + "Texture size mismatch, data:" + textureData.length + ", texture: " + this.size.w * this.size.h); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + if (useTexSubImage2D) { + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.size.w , this.size.h, this.format, gl.UNSIGNED_BYTE, textureData); + } else { + // texImage2D seems to be faster, thus keeping it as the default + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.size.w, this.size.h, 0, this.format, gl.UNSIGNED_BYTE, textureData); + } + }, + bind: function(n, program, name) { + var gl = this.gl; + if (!textureIDs) { + textureIDs = [gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2]; + } + gl.activeTexture(textureIDs[n]); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.uniform1i(gl.getUniformLocation(program.program, name), n); + } +}; +module.exports = Texture; + + +},{"../utils/assert":20}],9:[function(require,module,exports){ +"use strict"; + +/** + * Generic WebGL backed canvas that sets up: a quad to paint a texture on, appropriate vertex/fragment shaders, + * scene parameters and other things. Specialized versions of this class can be created by overriding several + * initialization methods. + + */ + +var Script = require('./Script'); +var error = require('../utils/error'); +var makePerspective = require('../utils/glUtils').makePerspective; +var Matrix = require('sylvester.js').Matrix; +var Class = require('uclass'); + + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", ` + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D texture; + void main(void) { + gl_FragColor = texture2D(texture, vTextureCoord); + } +`); + +var WebGLCanvas = new Class({ + + initialize : function(canvas, size, useFrameBuffer) { + + this.canvas = canvas; + this.size = size; + this.canvas.width = size.w; + this.canvas.height = size.h; + + this.onInitWebGL(); + this.onInitShaders(); + this.initBuffers(); + + if (useFrameBuffer) + this.initFramebuffer(); + + this.onInitTextures(); + this.initScene(); + }, + + +/** + * Initialize a frame buffer so that we can render off-screen. + */ + initFramebuffer : function() { + + var gl = this.gl; + + // Create framebuffer object and texture. + this.framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + this.framebufferTexture = new Texture(this.gl, this.size, gl.RGBA); + + // Create and allocate renderbuffer for depth data. + var renderbuffer = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.size.w, this.size.h); + + // Attach texture and renderbuffer to the framebuffer. + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.framebufferTexture.texture, 0); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer); + }, + + + +/** + * Initialize vertex and texture coordinate buffers for a plane. + */ + initBuffers : function () { + var tmp; + var gl = this.gl; + + // Create vertex position buffer. + this.quadVPBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer); + tmp = [ + 1.0, 1.0, 0.0, + -1.0, 1.0, 0.0, + 1.0, -1.0, 0.0, + -1.0, -1.0, 0.0]; + + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW); + this.quadVPBuffer.itemSize = 3; + this.quadVPBuffer.numItems = 4; + + /* + +--------------------+ + | -1,1 (1) | 1,1 (0) + | | + | | + | | + | | + | | + | -1,-1 (3) | 1,-1 (2) + +--------------------+ + */ + + var scaleX = 1.0; + var scaleY = 1.0; + + // Create vertex texture coordinate buffer. + this.quadVTCBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer); + tmp = [ + scaleX, 0.0, + 0.0, 0.0, + scaleX, scaleY, + 0.0, scaleY, + ]; + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tmp), gl.STATIC_DRAW); + }, + + + mvIdentity : function () { + this.mvMatrix = Matrix.I(4); + }, + + mvMultiply : function(m) { + this.mvMatrix = this.mvMatrix.x(m); + }, + + mvTranslate : function (m) { + this.mvMultiply(Matrix.Translation($V([m[0], m[1], m[2]])).ensure4x4()); + }, + + setMatrixUniforms : function () { + this.program.setMatrixUniform("uPMatrix", new Float32Array(this.perspectiveMatrix.flatten())); + this.program.setMatrixUniform("uMVMatrix", new Float32Array(this.mvMatrix.flatten())); + }, + + initScene : function() { + var gl = this.gl; + + // Establish the perspective with which we want to view the + // scene. Our field of view is 45 degrees, with a width/height + // ratio of 640:480, and we only want to see objects between 0.1 units + // and 100 units away from the camera. + + this.perspectiveMatrix = makePerspective(45, 1, 0.1, 100.0); + + // Set the drawing position to the "identity" point, which is + // the center of the scene. + this.mvIdentity(); + + // Now move the drawing position a bit to where we want to start + // drawing the square. + this.mvTranslate([0.0, 0.0, -2.4]); + + // Draw the cube by binding the array buffer to the cube's vertices + // array, setting attributes, and pushing it to GL. + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVPBuffer); + gl.vertexAttribPointer(this.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); + + // Set the texture coordinates attribute for the vertices. + + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVTCBuffer); + gl.vertexAttribPointer(this.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + + this.onInitSceneTextures(); + + this.setMatrixUniforms(); + + if (this.framebuffer) { + console.log("Bound Frame Buffer"); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + } + }, + + + + toString: function() { + return "WebGLCanvas Size: " + this.size; + }, + + checkLastError: function (operation) { + var err = this.gl.getError(); + if (err != this.gl.NO_ERROR) { + var name = this.glNames[err]; + name = (name !== undefined) ? name + "(" + err + ")": + ("Unknown WebGL ENUM (0x" + value.toString(16) + ")"); + if (operation) { + console.log("WebGL Error: %s, %s", operation, name); + } else { + console.log("WebGL Error: %s", name); + } + console.trace(); + } + }, + + onInitWebGL: function () { + try { + this.gl = this.canvas.getContext("experimental-webgl"); + } catch(e) {} + + if (!this.gl) { + error("Unable to initialize WebGL. Your browser may not support it."); + } + if (this.glNames) { + return; + } + this.glNames = {}; + for (var propertyName in this.gl) { + if (typeof this.gl[propertyName] == 'number') { + this.glNames[this.gl[propertyName]] = propertyName; + } + } + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");; + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + var gl = this.gl; + this.texture = new Texture(gl, this.size, gl.RGBA); + }, + + onInitSceneTextures: function () { + this.texture.bind(0, this.program, "texture"); + }, + + drawScene: function() { + this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); + }, + + readPixels: function(buffer) { + var gl = this.gl; + gl.readPixels(0, 0, this.size.w, this.size.h, gl.RGBA, gl.UNSIGNED_BYTE, buffer); + }, + + +}); + + + +module.exports = WebGLCanvas; + +},{"../utils/error":21,"../utils/glUtils":22,"./Script":6,"sylvester.js":12,"uclass":47}],10:[function(require,module,exports){ +"use strict"; +var Class = require('uclass'); + +var YUVCanvas = new Class({ + + Binds : ['decode'], + + initialize : function(canvas, size) { + this.canvas = canvas; + this.canvasCtx = this.canvas.getContext("2d"); + this.canvasBuffer = this.canvasCtx.createImageData(size.w, size.h); + }, + + decode : function (buffer, width, height) { + if (!buffer) + return; + + var lumaSize = width * height; + var chromaSize = lumaSize >> 2; + + var ybuf = buffer.subarray(0, lumaSize); + var ubuf = buffer.subarray(lumaSize, lumaSize + chromaSize); + var vbuf = buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize); + + for (var y = 0; y < height; y++) { + for (var x = 0; x < width; x++) { + var yIndex = x + y * width; + var uIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2); + var vIndex = ~~(y / 2) * ~~(width / 2) + ~~(x / 2); + var R = 1.164 * (ybuf[yIndex] - 16) + 1.596 * (vbuf[vIndex] - 128); + var G = 1.164 * (ybuf[yIndex] - 16) - 0.813 * (vbuf[vIndex] - 128) - 0.391 * (ubuf[uIndex] - 128); + var B = 1.164 * (ybuf[yIndex] - 16) + 2.018 * (ubuf[uIndex] - 128); + + var rgbIndex = yIndex * 4; + this.canvasBuffer.data[rgbIndex+0] = R; + this.canvasBuffer.data[rgbIndex+1] = G; + this.canvasBuffer.data[rgbIndex+2] = B; + this.canvasBuffer.data[rgbIndex+3] = 0xff; + } + } + + this.canvasCtx.putImageData(this.canvasBuffer, 0, 0); + +// var date = new Date(); + //console.log("WSAvcPlayer: Decode time: " + (date.getTime() - this.rcvtime) + " ms"); + }, + +}); + + +module.exports = YUVCanvas; +},{"uclass":47}],11:[function(require,module,exports){ +"use strict"; + +var Program = require('./Program'); +var Shader = require('./Shader'); +var Texture = require('./Texture'); +var Script = require('./Script'); +var WebGLCanvas = require('./WebGLCanvas'); + +var Class = require('uclass'); + +var vertexShaderScript = Script.createFromSource("x-shader/x-vertex", ` + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + varying highp vec2 vTextureCoord; + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } +`); + + +var fragmentShaderScript = Script.createFromSource("x-shader/x-fragment", ` + precision highp float; + varying highp vec2 vTextureCoord; + uniform sampler2D YTexture; + uniform sampler2D UTexture; + uniform sampler2D VTexture; + const mat4 YUV2RGB = mat4 + ( + 1.1643828125, 0, 1.59602734375, -.87078515625, + 1.1643828125, -.39176171875, -.81296875, .52959375, + 1.1643828125, 2.017234375, 0, -1.081390625, + 0, 0, 0, 1 + ); + + void main(void) { + gl_FragColor = vec4( texture2D(YTexture, vTextureCoord).x, texture2D(UTexture, vTextureCoord).x, texture2D(VTexture, vTextureCoord).x, 1) * YUV2RGB; + } +`); + + + + +var YUVWebGLCanvas = new Class({ + Extends : WebGLCanvas, + Binds : ['decode'], + + initialize : function(canvas, size) { + YUVWebGLCanvas.parent.initialize.call(this, canvas, size); + }, + + onInitShaders: function() { + this.program = new Program(this.gl); + this.program.attach(new Shader(this.gl, vertexShaderScript)); + this.program.attach(new Shader(this.gl, fragmentShaderScript)); + this.program.link(); + this.program.use(); + this.vertexPositionAttribute = this.program.getAttributeLocation("aVertexPosition"); + this.gl.enableVertexAttribArray(this.vertexPositionAttribute); + this.textureCoordAttribute = this.program.getAttributeLocation("aTextureCoord");; + this.gl.enableVertexAttribArray(this.textureCoordAttribute); + }, + + onInitTextures: function () { + console.log("creatingTextures: size: " + this.size); + this.YTexture = new Texture(this.gl, this.size); + this.UTexture = new Texture(this.gl, this.size.getHalfSize()); + this.VTexture = new Texture(this.gl, this.size.getHalfSize()); + }, + + onInitSceneTextures: function () { + this.YTexture.bind(0, this.program, "YTexture"); + this.UTexture.bind(1, this.program, "UTexture"); + this.VTexture.bind(2, this.program, "VTexture"); + }, + + fillYUVTextures: function(y, u, v) { + this.YTexture.fill(y); + this.UTexture.fill(u); + this.VTexture.fill(v); + }, + + decode: function(buffer, width, height) { + + if (!buffer) + return; + + var lumaSize = width * height; + var chromaSize = lumaSize >> 2; + + this.YTexture.fill(buffer.subarray(0, lumaSize)); + this.UTexture.fill(buffer.subarray(lumaSize, lumaSize + chromaSize)); + this.VTexture.fill(buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize)); + this.drawScene(); + }, + + toString: function() { + return "YUVCanvas Size: " + this.size; + } +}); + + + + + +module.exports = YUVWebGLCanvas; + +},{"./Program":5,"./Script":6,"./Shader":7,"./Texture":8,"./WebGLCanvas":9,"uclass":47}],12:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel + +var global = (Function('return this'))(); + +exports.Vector = require('./vector'); +global.$V = exports.Vector.create; +exports.Matrix = require('./matrix'); +global.$M = exports.Matrix.create; +exports.Line = require('./line'); +global.$L = exports.Line.create; +exports.Plane = require('./plane'); +global.$P = exports.Plane.create; +exports.Line.Segment = require('./line.segment'); +exports.Sylvester = require('./sylvester'); + +},{"./line":13,"./line.segment":14,"./matrix":15,"./plane":16,"./sylvester":17,"./vector":18}],13:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +var Vector = require('./vector'); +var Matrix = require('./matrix'); +var Plane = require('./plane'); +var Sylvester = require('./sylvester'); + +// Line class - depends on Vector, and some methods require Matrix and Plane. + +function Line() {} +Line.prototype = { + + // Returns true if the argument occupies the same space as the line + eql: function(line) { + return (this.isParallelTo(line) && this.contains(line.anchor)); + }, + + // Returns a copy of the line + dup: function() { + return Line.create(this.anchor, this.direction); + }, + + // Returns the result of translating the line by the given vector/array + translate: function(vector) { + var V = vector.elements || vector; + return Line.create([ + this.anchor.elements[0] + V[0], + this.anchor.elements[1] + V[1], + this.anchor.elements[2] + (V[2] || 0) + ], this.direction); + }, + + // Returns true if the line is parallel to the argument. Here, 'parallel to' + // means that the argument's direction is either parallel or antiparallel to + // the line's own direction. A line is parallel to a plane if the two do not + // have a unique intersection. + isParallelTo: function(obj) { + if (obj.normal || (obj.start && obj.end)) { return obj.isParallelTo(this); } + var theta = this.direction.angleFrom(obj.direction); + return (Math.abs(theta) <= Sylvester.precision || Math.abs(theta - Math.PI) <= Sylvester.precision); + }, + + // Returns the line's perpendicular distance from the argument, + // which can be a point, a line or a plane + distanceFrom: function(obj) { + if (obj.normal || (obj.start && obj.end)) { return obj.distanceFrom(this); } + if (obj.direction) { + // obj is a line + if (this.isParallelTo(obj)) { return this.distanceFrom(obj.anchor); } + var N = this.direction.cross(obj.direction).toUnitVector().elements; + var A = this.anchor.elements, B = obj.anchor.elements; + return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]); + } else { + // obj is a point + var P = obj.elements || obj; + var A = this.anchor.elements, D = this.direction.elements; + var PA1 = P[0] - A[0], PA2 = P[1] - A[1], PA3 = (P[2] || 0) - A[2]; + var modPA = Math.sqrt(PA1*PA1 + PA2*PA2 + PA3*PA3); + if (modPA === 0) return 0; + // Assumes direction vector is normalized + var cosTheta = (PA1 * D[0] + PA2 * D[1] + PA3 * D[2]) / modPA; + var sin2 = 1 - cosTheta*cosTheta; + return Math.abs(modPA * Math.sqrt(sin2 < 0 ? 0 : sin2)); + } + }, + + // Returns true iff the argument is a point on the line, or if the argument + // is a line segment lying within the receiver + contains: function(obj) { + if (obj.start && obj.end) { return this.contains(obj.start) && this.contains(obj.end); } + var dist = this.distanceFrom(obj); + return (dist !== null && dist <= Sylvester.precision); + }, + + // Returns the distance from the anchor of the given point. Negative values are + // returned for points that are in the opposite direction to the line's direction from + // the line's anchor point. + positionOf: function(point) { + if (!this.contains(point)) { return null; } + var P = point.elements || point; + var A = this.anchor.elements, D = this.direction.elements; + return (P[0] - A[0]) * D[0] + (P[1] - A[1]) * D[1] + ((P[2] || 0) - A[2]) * D[2]; + }, + + // Returns true iff the line lies in the given plane + liesIn: function(plane) { + return plane.contains(this); + }, + + // Returns true iff the line has a unique point of intersection with the argument + intersects: function(obj) { + if (obj.normal) { return obj.intersects(this); } + return (!this.isParallelTo(obj) && this.distanceFrom(obj) <= Sylvester.precision); + }, + + // Returns the unique intersection point with the argument, if one exists + intersectionWith: function(obj) { + if (obj.normal || (obj.start && obj.end)) { return obj.intersectionWith(this); } + if (!this.intersects(obj)) { return null; } + var P = this.anchor.elements, X = this.direction.elements, + Q = obj.anchor.elements, Y = obj.direction.elements; + var X1 = X[0], X2 = X[1], X3 = X[2], Y1 = Y[0], Y2 = Y[1], Y3 = Y[2]; + var PsubQ1 = P[0] - Q[0], PsubQ2 = P[1] - Q[1], PsubQ3 = P[2] - Q[2]; + var XdotQsubP = - X1*PsubQ1 - X2*PsubQ2 - X3*PsubQ3; + var YdotPsubQ = Y1*PsubQ1 + Y2*PsubQ2 + Y3*PsubQ3; + var XdotX = X1*X1 + X2*X2 + X3*X3; + var YdotY = Y1*Y1 + Y2*Y2 + Y3*Y3; + var XdotY = X1*Y1 + X2*Y2 + X3*Y3; + var k = (XdotQsubP * YdotY / XdotX + XdotY * YdotPsubQ) / (YdotY - XdotY * XdotY); + return Vector.create([P[0] + k*X1, P[1] + k*X2, P[2] + k*X3]); + }, + + // Returns the point on the line that is closest to the given point or line/line segment + pointClosestTo: function(obj) { + if (obj.start && obj.end) { + // obj is a line segment + var P = obj.pointClosestTo(this); + return (P === null) ? null : this.pointClosestTo(P); + } else if (obj.direction) { + // obj is a line + if (this.intersects(obj)) { return this.intersectionWith(obj); } + if (this.isParallelTo(obj)) { return null; } + var D = this.direction.elements, E = obj.direction.elements; + var D1 = D[0], D2 = D[1], D3 = D[2], E1 = E[0], E2 = E[1], E3 = E[2]; + // Create plane containing obj and the shared normal and intersect this with it + // Thank you: http://www.cgafaq.info/wiki/Line-line_distance + var x = (D3 * E1 - D1 * E3), y = (D1 * E2 - D2 * E1), z = (D2 * E3 - D3 * E2); + var N = [x * E3 - y * E2, y * E1 - z * E3, z * E2 - x * E1]; + var P = Plane.create(obj.anchor, N); + return P.intersectionWith(this); + } else { + // obj is a point + var P = obj.elements || obj; + if (this.contains(P)) { return Vector.create(P); } + var A = this.anchor.elements, D = this.direction.elements; + var D1 = D[0], D2 = D[1], D3 = D[2], A1 = A[0], A2 = A[1], A3 = A[2]; + var x = D1 * (P[1]-A2) - D2 * (P[0]-A1), y = D2 * ((P[2] || 0) - A3) - D3 * (P[1]-A2), + z = D3 * (P[0]-A1) - D1 * ((P[2] || 0) - A3); + var V = Vector.create([D2 * x - D3 * z, D3 * y - D1 * x, D1 * z - D2 * y]); + var k = this.distanceFrom(P) / V.modulus(); + return Vector.create([ + P[0] + V.elements[0] * k, + P[1] + V.elements[1] * k, + (P[2] || 0) + V.elements[2] * k + ]); + } + }, + + // Returns a copy of the line rotated by t radians about the given line. Works by + // finding the argument's closest point to this line's anchor point (call this C) and + // rotating the anchor about C. Also rotates the line's direction about the argument's. + // Be careful with this - the rotation axis' direction affects the outcome! + rotate: function(t, line) { + // If we're working in 2D + if (typeof(line.direction) == 'undefined') { line = Line.create(line.to3D(), Vector.k); } + var R = Matrix.Rotation(t, line.direction).elements; + var C = line.pointClosestTo(this.anchor).elements; + var A = this.anchor.elements, D = this.direction.elements; + var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2]; + var x = A1 - C1, y = A2 - C2, z = A3 - C3; + return Line.create([ + C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z, + C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z, + C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z + ], [ + R[0][0] * D[0] + R[0][1] * D[1] + R[0][2] * D[2], + R[1][0] * D[0] + R[1][1] * D[1] + R[1][2] * D[2], + R[2][0] * D[0] + R[2][1] * D[1] + R[2][2] * D[2] + ]); + }, + + // Returns a copy of the line with its direction vector reversed. + // Useful when using lines for rotations. + reverse: function() { + return Line.create(this.anchor, this.direction.x(-1)); + }, + + // Returns the line's reflection in the given point or line + reflectionIn: function(obj) { + if (obj.normal) { + // obj is a plane + var A = this.anchor.elements, D = this.direction.elements; + var A1 = A[0], A2 = A[1], A3 = A[2], D1 = D[0], D2 = D[1], D3 = D[2]; + var newA = this.anchor.reflectionIn(obj).elements; + // Add the line's direction vector to its anchor, then mirror that in the plane + var AD1 = A1 + D1, AD2 = A2 + D2, AD3 = A3 + D3; + var Q = obj.pointClosestTo([AD1, AD2, AD3]).elements; + var newD = [Q[0] + (Q[0] - AD1) - newA[0], Q[1] + (Q[1] - AD2) - newA[1], Q[2] + (Q[2] - AD3) - newA[2]]; + return Line.create(newA, newD); + } else if (obj.direction) { + // obj is a line - reflection obtained by rotating PI radians about obj + return this.rotate(Math.PI, obj); + } else { + // obj is a point - just reflect the line's anchor in it + var P = obj.elements || obj; + return Line.create(this.anchor.reflectionIn([P[0], P[1], (P[2] || 0)]), this.direction); + } + }, + + // Set the line's anchor point and direction. + setVectors: function(anchor, direction) { + // Need to do this so that line's properties are not + // references to the arguments passed in + anchor = Vector.create(anchor); + direction = Vector.create(direction); + if (anchor.elements.length == 2) {anchor.elements.push(0); } + if (direction.elements.length == 2) { direction.elements.push(0); } + if (anchor.elements.length > 3 || direction.elements.length > 3) { return null; } + var mod = direction.modulus(); + if (mod === 0) { return null; } + this.anchor = anchor; + this.direction = Vector.create([ + direction.elements[0] / mod, + direction.elements[1] / mod, + direction.elements[2] / mod + ]); + return this; + } +}; + +// Constructor function +Line.create = function(anchor, direction) { + var L = new Line(); + return L.setVectors(anchor, direction); +}; + +// Axes +Line.X = Line.create(Vector.Zero(3), Vector.i); +Line.Y = Line.create(Vector.Zero(3), Vector.j); +Line.Z = Line.create(Vector.Zero(3), Vector.k); + +module.exports = Line; + +},{"./matrix":15,"./plane":16,"./sylvester":17,"./vector":18}],14:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// Line.Segment class - depends on Line and its dependencies. + +var Line = require('./line'); +var Vector = require('./vector'); + +Line.Segment = function() {}; +Line.Segment.prototype = { + + // Returns true iff the line segment is equal to the argument + eql: function(segment) { + return (this.start.eql(segment.start) && this.end.eql(segment.end)) || + (this.start.eql(segment.end) && this.end.eql(segment.start)); + }, + + // Returns a copy of the line segment + dup: function() { + return Line.Segment.create(this.start, this.end); + }, + + // Returns the length of the line segment + length: function() { + var A = this.start.elements, B = this.end.elements; + var C1 = B[0] - A[0], C2 = B[1] - A[1], C3 = B[2] - A[2]; + return Math.sqrt(C1*C1 + C2*C2 + C3*C3); + }, + + // Returns the line segment as a vector equal to its + // end point relative to its endpoint + toVector: function() { + var A = this.start.elements, B = this.end.elements; + return Vector.create([B[0] - A[0], B[1] - A[1], B[2] - A[2]]); + }, + + // Returns the segment's midpoint as a vector + midpoint: function() { + var A = this.start.elements, B = this.end.elements; + return Vector.create([(B[0] + A[0])/2, (B[1] + A[1])/2, (B[2] + A[2])/2]); + }, + + // Returns the plane that bisects the segment + bisectingPlane: function() { + return Plane.create(this.midpoint(), this.toVector()); + }, + + // Returns the result of translating the line by the given vector/array + translate: function(vector) { + var V = vector.elements || vector; + var S = this.start.elements, E = this.end.elements; + return Line.Segment.create( + [S[0] + V[0], S[1] + V[1], S[2] + (V[2] || 0)], + [E[0] + V[0], E[1] + V[1], E[2] + (V[2] || 0)] + ); + }, + + // Returns true iff the line segment is parallel to the argument. It simply forwards + // the method call onto its line property. + isParallelTo: function(obj) { + return this.line.isParallelTo(obj); + }, + + // Returns the distance between the argument and the line segment's closest point to the argument + distanceFrom: function(obj) { + var P = this.pointClosestTo(obj); + return (P === null) ? null : P.distanceFrom(obj); + }, + + // Returns true iff the given point lies on the segment + contains: function(obj) { + if (obj.start && obj.end) { return this.contains(obj.start) && this.contains(obj.end); } + var P = (obj.elements || obj).slice(); + if (P.length == 2) { P.push(0); } + if (this.start.eql(P)) { return true; } + var S = this.start.elements; + var V = Vector.create([S[0] - P[0], S[1] - P[1], S[2] - (P[2] || 0)]); + var vect = this.toVector(); + return V.isAntiparallelTo(vect) && V.modulus() <= vect.modulus(); + }, + + // Returns true iff the line segment intersects the argument + intersects: function(obj) { + return (this.intersectionWith(obj) !== null); + }, + + // Returns the unique point of intersection with the argument + intersectionWith: function(obj) { + if (!this.line.intersects(obj)) { return null; } + var P = this.line.intersectionWith(obj); + return (this.contains(P) ? P : null); + }, + + // Returns the point on the line segment closest to the given object + pointClosestTo: function(obj) { + if (obj.normal) { + // obj is a plane + var V = this.line.intersectionWith(obj); + if (V === null) { return null; } + return this.pointClosestTo(V); + } else { + // obj is a line (segment) or point + var P = this.line.pointClosestTo(obj); + if (P === null) { return null; } + if (this.contains(P)) { return P; } + return (this.line.positionOf(P) < 0 ? this.start : this.end).dup(); + } + }, + + // Set the start and end-points of the segment + setPoints: function(startPoint, endPoint) { + startPoint = Vector.create(startPoint).to3D(); + endPoint = Vector.create(endPoint).to3D(); + if (startPoint === null || endPoint === null) { return null; } + this.line = Line.create(startPoint, endPoint.subtract(startPoint)); + this.start = startPoint; + this.end = endPoint; + return this; + } +}; + +// Constructor function +Line.Segment.create = function(v1, v2) { + var S = new Line.Segment(); + return S.setPoints(v1, v2); +}; + +module.exports = Line.Segment; + +},{"./line":13,"./vector":18}],15:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// Matrix class - depends on Vector. + +var Sylvester = require('./sylvester'); +var Vector = require('./vector'); + +// augment a matrix M with identity rows/cols +function identSize(M, m, n, k) { + var e = M.elements; + var i = k - 1; + + while(i--) { + var row = []; + + for(var j = 0; j < n; j++) + row.push(j == i ? 1 : 0); + + e.unshift(row); + } + + for(var i = k - 1; i < m; i++) { + while(e[i].length < n) + e[i].unshift(0); + } + + return $M(e); +} + +function pca(X) { + var Sigma = X.transpose().x(X).x(1 / X.rows()); + var svd = Sigma.svd(); + return {U: svd.U, S: svd.S}; +} + +// singular value decomposition in pure javascript +function svdJs() { + var A = this; + var V = Matrix.I(A.rows()); + var S = A.transpose(); + var U = Matrix.I(A.cols()); + var err = Number.MAX_VALUE; + var i = 0; + var maxLoop = 100; + + while(err > 2.2737e-13 && i < maxLoop) { + var qr = S.transpose().qrJs(); + S = qr.R; + V = V.x(qr.Q); + qr = S.transpose().qrJs(); + U = U.x(qr.Q); + S = qr.R; + + var e = S.triu(1).unroll().norm(); + var f = S.diagonal().norm(); + + if(f == 0) + f = 1; + + err = e / f; + + i++; + } + + var ss = S.diagonal(); + var s = []; + + for(var i = 1; i <= ss.cols(); i++) { + var ssn = ss.e(i); + s.push(Math.abs(ssn)); + + if(ssn < 0) { + for(var j = 0; j < U.rows(); j++) { + V.elements[j][i - 1] = -(V.elements[j][i - 1]); + } + } + } + + return {U: U, S: $V(s).toDiagonalMatrix(), V: V}; +} + + + +// QR decomposition in pure javascript +function qrJs() { + var m = this.rows(); + var n = this.cols(); + var Q = Matrix.I(m); + var A = this; + + for(var k = 1; k < Math.min(m, n); k++) { + var ak = A.slice(k, 0, k, k).col(1); + var oneZero = [1]; + + while(oneZero.length <= m - k) + oneZero.push(0); + + oneZero = $V(oneZero); + var vk = ak.add(oneZero.x(ak.norm() * Math.sign(ak.e(1)))); + var Vk = $M(vk); + var Hk = Matrix.I(m - k + 1).subtract(Vk.x(2).x(Vk.transpose()).div(Vk.transpose().x(Vk).e(1, 1))); + var Qk = identSize(Hk, m, n, k); + A = Qk.x(A); + // slow way to compute Q + Q = Q.x(Qk); + } + + return {Q: Q, R: A}; +} + + + + +function Matrix() {} +Matrix.prototype = { + // solve a system of linear equations (work in progress) + solve: function(b) { + var lu = this.lu(); + b = lu.P.x(b); + var y = lu.L.forwardSubstitute(b); + var x = lu.U.backSubstitute(y); + return lu.P.x(x); + //return this.inv().x(b); + }, + + // project a matrix onto a lower dim + pcaProject: function(k, U) { + var U = U || pca(this).U; + var Ureduce= U.slice(1, U.rows(), 1, k); + return {Z: this.x(Ureduce), U: U}; + }, + + // recover a matrix to a higher dimension + pcaRecover: function(U) { + var k = this.cols(); + var Ureduce = U.slice(1, U.rows(), 1, k); + return this.x(Ureduce.transpose()); + }, + + // grab the upper triangular part of the matrix + triu: function(k) { + if(!k) + k = 0; + + return this.map(function(x, i, j) { + return j - i >= k ? x : 0; + }); + }, + + // unroll a matrix into a vector + unroll: function() { + var v = []; + + for(var i = 1; i <= this.cols(); i++) { + for(var j = 1; j <= this.rows(); j++) { + v.push(this.e(j, i)); + } + } + + return $V(v); + }, + + // return a sub-block of the matrix + slice: function(startRow, endRow, startCol, endCol) { + var x = []; + + if(endRow == 0) + endRow = this.rows(); + + if(endCol == 0) + endCol = this.cols(); + + for(i = startRow; i <= endRow; i++) { + var row = []; + + for(j = startCol; j <= endCol; j++) { + row.push(this.e(i, j)); + } + + x.push(row); + } + + return $M(x); + }, + + // Returns element (i,j) of the matrix + e: function(i,j) { + if (i < 1 || i > this.elements.length || j < 1 || j > this.elements[0].length) { return null; } + return this.elements[i - 1][j - 1]; + }, + + // Returns row k of the matrix as a vector + row: function(i) { + if (i > this.elements.length) { return null; } + return $V(this.elements[i - 1]); + }, + + // Returns column k of the matrix as a vector + col: function(j) { + if (j > this.elements[0].length) { return null; } + var col = [], n = this.elements.length; + for (var i = 0; i < n; i++) { col.push(this.elements[i][j - 1]); } + return $V(col); + }, + + // Returns the number of rows/columns the matrix has + dimensions: function() { + return {rows: this.elements.length, cols: this.elements[0].length}; + }, + + // Returns the number of rows in the matrix + rows: function() { + return this.elements.length; + }, + + // Returns the number of columns in the matrix + cols: function() { + return this.elements[0].length; + }, + + approxEql: function(matrix) { + return this.eql(matrix, Sylvester.approxPrecision); + }, + + // Returns true iff the matrix is equal to the argument. You can supply + // a vector as the argument, in which case the receiver must be a + // one-column matrix equal to the vector. + eql: function(matrix, precision) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + if (this.elements.length != M.length || + this.elements[0].length != M[0].length) { return false; } + var i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { j = nj; + while (j--) { + if (Math.abs(this.elements[i][j] - M[i][j]) > (precision || Sylvester.precision)) { return false; } + } + } + return true; + }, + + // Returns a copy of the matrix + dup: function() { + return Matrix.create(this.elements); + }, + + // Maps the matrix to another matrix (of the same dimensions) according to the given function + map: function(fn) { + var els = [], i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { j = nj; + els[i] = []; + while (j--) { + els[i][j] = fn(this.elements[i][j], i + 1, j + 1); + } + } + return Matrix.create(els); + }, + + // Returns true iff the argument has the same dimensions as the matrix + isSameSizeAs: function(matrix) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + return (this.elements.length == M.length && + this.elements[0].length == M[0].length); + }, + + // Returns the result of adding the argument to the matrix + add: function(matrix) { + if(typeof(matrix) == 'number') { + return this.map(function(x, i, j) { return x + matrix}); + } else { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + if (!this.isSameSizeAs(M)) { return null; } + return this.map(function(x, i, j) { return x + M[i - 1][j - 1]; }); + } + }, + + // Returns the result of subtracting the argument from the matrix + subtract: function(matrix) { + if(typeof(matrix) == 'number') { + return this.map(function(x, i, j) { return x - matrix}); + } else { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + if (!this.isSameSizeAs(M)) { return null; } + return this.map(function(x, i, j) { return x - M[i - 1][j - 1]; }); + } + }, + + // Returns true iff the matrix can multiply the argument from the left + canMultiplyFromLeft: function(matrix) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + // this.columns should equal matrix.rows + return (this.elements[0].length == M.length); + }, + + // Returns the result of a multiplication-style operation the matrix from the right by the argument. + // If the argument is a scalar then just operate on all the elements. If the argument is + // a vector, a vector is returned, which saves you having to remember calling + // col(1) on the result. + mulOp: function(matrix, op) { + if (!matrix.elements) { + return this.map(function(x) { return op(x, matrix); }); + } + + var returnVector = matrix.modulus ? true : false; + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') + M = Matrix.create(M).elements; + if (!this.canMultiplyFromLeft(M)) + return null; + var e = this.elements, rowThis, rowElem, elements = [], + sum, m = e.length, n = M[0].length, o = e[0].length, i = m, j, k; + + while (i--) { + rowElem = []; + rowThis = e[i]; + j = n; + + while (j--) { + sum = 0; + k = o; + + while (k--) { + sum += op(rowThis[k], M[k][j]); + } + + rowElem[j] = sum; + } + + elements[i] = rowElem; + } + + var M = Matrix.create(elements); + return returnVector ? M.col(1) : M; + }, + + // Returns the result of dividing the matrix from the right by the argument. + // If the argument is a scalar then just divide all the elements. If the argument is + // a vector, a vector is returned, which saves you having to remember calling + // col(1) on the result. + div: function(matrix) { + return this.mulOp(matrix, function(x, y) { return x / y}); + }, + + // Returns the result of multiplying the matrix from the right by the argument. + // If the argument is a scalar then just multiply all the elements. If the argument is + // a vector, a vector is returned, which saves you having to remember calling + // col(1) on the result. + multiply: function(matrix) { + return this.mulOp(matrix, function(x, y) { return x * y}); + }, + + x: function(matrix) { return this.multiply(matrix); }, + + elementMultiply: function(v) { + return this.map(function(k, i, j) { + return v.e(i, j) * k; + }); + }, + + // sum all elements in the matrix + sum: function() { + var sum = 0; + + this.map(function(x) { sum += x;}); + + return sum; + }, + + // Returns a Vector of each colum averaged. + mean: function() { + var dim = this.dimensions(); + var r = []; + for (var i = 1; i <= dim.cols; i++) { + r.push(this.col(i).sum() / dim.rows); + } + return $V(r); + }, + + column: function(n) { + return this.col(n); + }, + + // element-wise log + log: function() { + return this.map(function(x) { return Math.log(x); }); + }, + + // Returns a submatrix taken from the matrix + // Argument order is: start row, start col, nrows, ncols + // Element selection wraps if the required index is outside the matrix's bounds, so you could + // use this to perform row/column cycling or copy-augmenting. + minor: function(a, b, c, d) { + var elements = [], ni = c, i, nj, j; + var rows = this.elements.length, cols = this.elements[0].length; + while (ni--) { + i = c - ni - 1; + elements[i] = []; + nj = d; + while (nj--) { + j = d - nj - 1; + elements[i][j] = this.elements[(a + i - 1) % rows][(b + j - 1) % cols]; + } + } + return Matrix.create(elements); + }, + + // Returns the transpose of the matrix + transpose: function() { + var rows = this.elements.length, i, cols = this.elements[0].length, j; + var elements = [], i = cols; + while (i--) { + j = rows; + elements[i] = []; + while (j--) { + elements[i][j] = this.elements[j][i]; + } + } + return Matrix.create(elements); + }, + + // Returns true iff the matrix is square + isSquare: function() { + return (this.elements.length == this.elements[0].length); + }, + + // Returns the (absolute) largest element of the matrix + max: function() { + var m = 0, i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { + j = nj; + while (j--) { + if (Math.abs(this.elements[i][j]) > Math.abs(m)) { m = this.elements[i][j]; } + } + } + return m; + }, + + // Returns the indeces of the first match found by reading row-by-row from left to right + indexOf: function(x) { + var index = null, ni = this.elements.length, i, nj = this.elements[0].length, j; + for (i = 0; i < ni; i++) { + for (j = 0; j < nj; j++) { + if (this.elements[i][j] == x) { return {i: i + 1, j: j + 1}; } + } + } + return null; + }, + + // If the matrix is square, returns the diagonal elements as a vector. + // Otherwise, returns null. + diagonal: function() { + if (!this.isSquare) { return null; } + var els = [], n = this.elements.length; + for (var i = 0; i < n; i++) { + els.push(this.elements[i][i]); + } + return $V(els); + }, + + // Make the matrix upper (right) triangular by Gaussian elimination. + // This method only adds multiples of rows to other rows. No rows are + // scaled up or switched, and the determinant is preserved. + toRightTriangular: function() { + var M = this.dup(), els; + var n = this.elements.length, i, j, np = this.elements[0].length, p; + for (i = 0; i < n; i++) { + if (M.elements[i][i] == 0) { + for (j = i + 1; j < n; j++) { + if (M.elements[j][i] != 0) { + els = []; + for (p = 0; p < np; p++) { els.push(M.elements[i][p] + M.elements[j][p]); } + M.elements[i] = els; + break; + } + } + } + if (M.elements[i][i] != 0) { + for (j = i + 1; j < n; j++) { + var multiplier = M.elements[j][i] / M.elements[i][i]; + els = []; + for (p = 0; p < np; p++) { + // Elements with column numbers up to an including the number + // of the row that we're subtracting can safely be set straight to + // zero, since that's the point of this routine and it avoids having + // to loop over and correct rounding errors later + els.push(p <= i ? 0 : M.elements[j][p] - M.elements[i][p] * multiplier); + } + M.elements[j] = els; + } + } + } + return M; + }, + + toUpperTriangular: function() { return this.toRightTriangular(); }, + + // Returns the determinant for square matrices + determinant: function() { + if (!this.isSquare()) { return null; } + if (this.cols == 1 && this.rows == 1) { return this.row(1); } + if (this.cols == 0 && this.rows == 0) { return 1; } + var M = this.toRightTriangular(); + var det = M.elements[0][0], n = M.elements.length; + for (var i = 1; i < n; i++) { + det = det * M.elements[i][i]; + } + return det; + }, + det: function() { return this.determinant(); }, + + // Returns true iff the matrix is singular + isSingular: function() { + return (this.isSquare() && this.determinant() === 0); + }, + + // Returns the trace for square matrices + trace: function() { + if (!this.isSquare()) { return null; } + var tr = this.elements[0][0], n = this.elements.length; + for (var i = 1; i < n; i++) { + tr += this.elements[i][i]; + } + return tr; + }, + + tr: function() { return this.trace(); }, + + // Returns the rank of the matrix + rank: function() { + var M = this.toRightTriangular(), rank = 0; + var i = this.elements.length, nj = this.elements[0].length, j; + while (i--) { + j = nj; + while (j--) { + if (Math.abs(M.elements[i][j]) > Sylvester.precision) { rank++; break; } + } + } + return rank; + }, + + rk: function() { return this.rank(); }, + + // Returns the result of attaching the given argument to the right-hand side of the matrix + augment: function(matrix) { + var M = matrix.elements || matrix; + if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; } + var T = this.dup(), cols = T.elements[0].length; + var i = T.elements.length, nj = M[0].length, j; + if (i != M.length) { return null; } + while (i--) { + j = nj; + while (j--) { + T.elements[i][cols + j] = M[i][j]; + } + } + return T; + }, + + // Returns the inverse (if one exists) using Gauss-Jordan + inverse: function() { + if (!this.isSquare() || this.isSingular()) { return null; } + var n = this.elements.length, i = n, j; + var M = this.augment(Matrix.I(n)).toRightTriangular(); + var np = M.elements[0].length, p, els, divisor; + var inverse_elements = [], new_element; + // Matrix is non-singular so there will be no zeros on the diagonal + // Cycle through rows from last to first + while (i--) { + // First, normalise diagonal elements to 1 + els = []; + inverse_elements[i] = []; + divisor = M.elements[i][i]; + for (p = 0; p < np; p++) { + new_element = M.elements[i][p] / divisor; + els.push(new_element); + // Shuffle off the current row of the right hand side into the results + // array as it will not be modified by later runs through this loop + if (p >= n) { inverse_elements[i].push(new_element); } + } + M.elements[i] = els; + // Then, subtract this row from those above it to + // give the identity matrix on the left hand side + j = i; + while (j--) { + els = []; + for (p = 0; p < np; p++) { + els.push(M.elements[j][p] - M.elements[i][p] * M.elements[j][i]); + } + M.elements[j] = els; + } + } + return Matrix.create(inverse_elements); + }, + + inv: function() { return this.inverse(); }, + + // Returns the result of rounding all the elements + round: function() { + return this.map(function(x) { return Math.round(x); }); + }, + + // Returns a copy of the matrix with elements set to the given value if they + // differ from it by less than Sylvester.precision + snapTo: function(x) { + return this.map(function(p) { + return (Math.abs(p - x) <= Sylvester.precision) ? x : p; + }); + }, + + // Returns a string representation of the matrix + inspect: function() { + var matrix_rows = []; + var n = this.elements.length; + for (var i = 0; i < n; i++) { + matrix_rows.push($V(this.elements[i]).inspect()); + } + return matrix_rows.join('\n'); + }, + + // Returns a array representation of the matrix + toArray: function() { + var matrix_rows = []; + var n = this.elements.length; + for (var i = 0; i < n; i++) { + matrix_rows.push(this.elements[i]); + } + return matrix_rows; + }, + + + // Set the matrix's elements from an array. If the argument passed + // is a vector, the resulting matrix will be a single column. + setElements: function(els) { + var i, j, elements = els.elements || els; + if (typeof(elements[0][0]) != 'undefined') { + i = elements.length; + this.elements = []; + while (i--) { + j = elements[i].length; + this.elements[i] = []; + while (j--) { + this.elements[i][j] = elements[i][j]; + } + } + return this; + } + var n = elements.length; + this.elements = []; + for (i = 0; i < n; i++) { + this.elements.push([elements[i]]); + } + return this; + }, + + // return the indexes of the columns with the largest value + // for each row + maxColumnIndexes: function() { + var maxes = []; + + for(var i = 1; i <= this.rows(); i++) { + var max = null; + var maxIndex = -1; + + for(var j = 1; j <= this.cols(); j++) { + if(max === null || this.e(i, j) > max) { + max = this.e(i, j); + maxIndex = j; + } + } + + maxes.push(maxIndex); + } + + return $V(maxes); + }, + + // return the largest values in each row + maxColumns: function() { + var maxes = []; + + for(var i = 1; i <= this.rows(); i++) { + var max = null; + + for(var j = 1; j <= this.cols(); j++) { + if(max === null || this.e(i, j) > max) { + max = this.e(i, j); + } + } + + maxes.push(max); + } + + return $V(maxes); + }, + + // return the indexes of the columns with the smallest values + // for each row + minColumnIndexes: function() { + var mins = []; + + for(var i = 1; i <= this.rows(); i++) { + var min = null; + var minIndex = -1; + + for(var j = 1; j <= this.cols(); j++) { + if(min === null || this.e(i, j) < min) { + min = this.e(i, j); + minIndex = j; + } + } + + mins.push(minIndex); + } + + return $V(mins); + }, + + // return the smallest values in each row + minColumns: function() { + var mins = []; + + for(var i = 1; i <= this.rows(); i++) { + var min = null; + + for(var j = 1; j <= this.cols(); j++) { + if(min === null || this.e(i, j) < min) { + min = this.e(i, j); + } + } + + mins.push(min); + } + + return $V(mins); + }, + + // perorm a partial pivot on the matrix. essentially move the largest + // row below-or-including the pivot and replace the pivot's row with it. + // a pivot matrix is returned so multiplication can perform the transform. + partialPivot: function(k, j, P, A, L) { + var maxIndex = 0; + var maxValue = 0; + + for(var i = k; i <= A.rows(); i++) { + if(Math.abs(A.e(i, j)) > maxValue) { + maxValue = Math.abs(A.e(k, j)); + maxIndex = i; + } + } + + if(maxIndex != k) { + var tmp = A.elements[k - 1]; + A.elements[k - 1] = A.elements[maxIndex - 1]; + A.elements[maxIndex - 1] = tmp; + + P.elements[k - 1][k - 1] = 0; + P.elements[k - 1][maxIndex - 1] = 1; + P.elements[maxIndex - 1][maxIndex - 1] = 0; + P.elements[maxIndex - 1][k - 1] = 1; + } + + return P; + }, + + // solve lower-triangular matrix * x = b via forward substitution + forwardSubstitute: function(b) { + var xa = []; + + for(var i = 1; i <= this.rows(); i++) { + var w = 0; + + for(var j = 1; j < i; j++) { + w += this.e(i, j) * xa[j - 1]; + } + + xa.push((b.e(i) - w) / this.e(i, i)); + } + + return $V(xa); + }, + + // solve an upper-triangular matrix * x = b via back substitution + backSubstitute: function(b) { + var xa = []; + + for(var i = this.rows(); i > 0; i--) { + var w = 0; + + for(var j = this.cols(); j > i; j--) { + w += this.e(i, j) * xa[this.rows() - j]; + } + + xa.push((b.e(i) - w) / this.e(i, i)); + } + + return $V(xa.reverse()); + }, + + luJs: luJs, + svdJs: svdJs, + qrJs: qrJs, +}; + + +var tolerance = 1.4901e-08; + +// pure Javascript LU factorization +function luJs() { + var A = this.dup(); + var L = Matrix.I(A.rows()); + var P = Matrix.I(A.rows()); + var U = Matrix.Zeros(A.rows(), A.cols()); + var p = 1; + + for(var k = 1; k <= Math.min(A.cols(), A.rows()); k++) { + P = A.partialPivot(k, p, P, A, L); + + for(var i = k + 1; i <= A.rows(); i++) { + var l = A.e(i, p) / A.e(k, p); + L.elements[i - 1][k - 1] = l; + + for(var j = k + 1 ; j <= A.cols(); j++) { + A.elements[i - 1][j - 1] -= A.e(k, j) * l; + } + } + + for(var j = k; j <= A.cols(); j++) { + U.elements[k - 1][j - 1] = A.e(k, j); + } + + if(p < A.cols()) + p++; + } + + return {L: L, U: U, P: P}; +} + + + +Matrix.prototype.svd = svdJs; +Matrix.prototype.qr = qrJs; +Matrix.prototype.lu = luJs; + +// Constructor function +Matrix.create = function(aElements) { + var M = new Matrix().setElements(aElements); + return M; +}; + +// Identity matrix of size n +Matrix.I = function(n) { + var els = [], i = n, j; + while (i--) { + j = n; + els[i] = []; + while (j--) { + els[i][j] = (i == j) ? 1 : 0; + } + } + return Matrix.create(els); +}; + +Matrix.loadFile = function(file) { + var fs = require('fs'); + var contents = fs.readFileSync(file, 'utf-8'); + var matrix = []; + + var rowArray = contents.split('\n'); + for (var i = 0; i < rowArray.length; i++) { + var d = rowArray[i].split(','); + if (d.length > 1) { + matrix.push(d); + } + } + + var M = new Matrix(); + return M.setElements(matrix); +}; + +// Diagonal matrix - all off-diagonal elements are zero +Matrix.Diagonal = function(elements) { + var i = elements.length; + var M = Matrix.I(i); + while (i--) { + M.elements[i][i] = elements[i]; + } + return M; +}; + +// Rotation matrix about some axis. If no axis is +// supplied, assume we're after a 2D transform +Matrix.Rotation = function(theta, a) { + if (!a) { + return Matrix.create([ + [Math.cos(theta), -Math.sin(theta)], + [Math.sin(theta), Math.cos(theta)] + ]); + } + var axis = a.dup(); + if (axis.elements.length != 3) { return null; } + var mod = axis.modulus(); + var x = axis.elements[0] / mod, y = axis.elements[1] / mod, z = axis.elements[2] / mod; + var s = Math.sin(theta), c = Math.cos(theta), t = 1 - c; + // Formula derived here: http://www.gamedev.net/reference/articles/article1199.asp + // That proof rotates the co-ordinate system so theta + // becomes -theta and sin becomes -sin here. + return Matrix.create([ + [t * x * x + c, t * x * y - s * z, t * x * z + s * y], + [t * x * y + s * z, t * y * y + c, t * y * z - s * x], + [t * x * z - s * y, t * y * z + s * x, t * z * z + c] + ]); +}; + +// Special case rotations +Matrix.RotationX = function(t) { + var c = Math.cos(t), s = Math.sin(t); + return Matrix.create([ + [1, 0, 0], + [0, c, -s], + [0, s, c] + ]); +}; + +Matrix.RotationY = function(t) { + var c = Math.cos(t), s = Math.sin(t); + return Matrix.create([ + [c, 0, s], + [0, 1, 0], + [-s, 0, c] + ]); +}; + +Matrix.RotationZ = function(t) { + var c = Math.cos(t), s = Math.sin(t); + return Matrix.create([ + [c, -s, 0], + [s, c, 0], + [0, 0, 1] + ]); +}; + +// Random matrix of n rows, m columns +Matrix.Random = function(n, m) { + if (arguments.length === 1) m = n; + return Matrix.Zero(n, m).map( + function() { return Math.random(); } + ); +}; + +Matrix.Fill = function(n, m, v) { + if (arguments.length === 2) { + v = m; + m = n; + } + + var els = [], i = n, j; + + while (i--) { + j = m; + els[i] = []; + + while (j--) { + els[i][j] = v; + } + } + + return Matrix.create(els); +}; + +// Matrix filled with zeros +Matrix.Zero = function(n, m) { + return Matrix.Fill(n, m, 0); +}; + +// Matrix filled with zeros +Matrix.Zeros = function(n, m) { + return Matrix.Zero(n, m); +}; + +// Matrix filled with ones +Matrix.One = function(n, m) { + return Matrix.Fill(n, m, 1); +}; + +// Matrix filled with ones +Matrix.Ones = function(n, m) { + return Matrix.One(n, m); +}; + +module.exports = Matrix; + +},{"./sylvester":17,"./vector":18,"fs":undefined}],16:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// Plane class - depends on Vector. Some methods require Matrix and Line. +var Vector = require('./vector'); +var Matrix = require('./matrix'); +var Line = require('./line'); + +var Sylvester = require('./sylvester'); + +function Plane() {} +Plane.prototype = { + + // Returns true iff the plane occupies the same space as the argument + eql: function(plane) { + return (this.contains(plane.anchor) && this.isParallelTo(plane)); + }, + + // Returns a copy of the plane + dup: function() { + return Plane.create(this.anchor, this.normal); + }, + + // Returns the result of translating the plane by the given vector + translate: function(vector) { + var V = vector.elements || vector; + return Plane.create([ + this.anchor.elements[0] + V[0], + this.anchor.elements[1] + V[1], + this.anchor.elements[2] + (V[2] || 0) + ], this.normal); + }, + + // Returns true iff the plane is parallel to the argument. Will return true + // if the planes are equal, or if you give a line and it lies in the plane. + isParallelTo: function(obj) { + var theta; + if (obj.normal) { + // obj is a plane + theta = this.normal.angleFrom(obj.normal); + return (Math.abs(theta) <= Sylvester.precision || Math.abs(Math.PI - theta) <= Sylvester.precision); + } else if (obj.direction) { + // obj is a line + return this.normal.isPerpendicularTo(obj.direction); + } + return null; + }, + + // Returns true iff the receiver is perpendicular to the argument + isPerpendicularTo: function(plane) { + var theta = this.normal.angleFrom(plane.normal); + return (Math.abs(Math.PI/2 - theta) <= Sylvester.precision); + }, + + // Returns the plane's distance from the given object (point, line or plane) + distanceFrom: function(obj) { + if (this.intersects(obj) || this.contains(obj)) { return 0; } + if (obj.anchor) { + // obj is a plane or line + var A = this.anchor.elements, B = obj.anchor.elements, N = this.normal.elements; + return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]); + } else { + // obj is a point + var P = obj.elements || obj; + var A = this.anchor.elements, N = this.normal.elements; + return Math.abs((A[0] - P[0]) * N[0] + (A[1] - P[1]) * N[1] + (A[2] - (P[2] || 0)) * N[2]); + } + }, + + // Returns true iff the plane contains the given point or line + contains: function(obj) { + if (obj.normal) { return null; } + if (obj.direction) { + return (this.contains(obj.anchor) && this.contains(obj.anchor.add(obj.direction))); + } else { + var P = obj.elements || obj; + var A = this.anchor.elements, N = this.normal.elements; + var diff = Math.abs(N[0]*(A[0] - P[0]) + N[1]*(A[1] - P[1]) + N[2]*(A[2] - (P[2] || 0))); + return (diff <= Sylvester.precision); + } + }, + + // Returns true iff the plane has a unique point/line of intersection with the argument + intersects: function(obj) { + if (typeof(obj.direction) == 'undefined' && typeof(obj.normal) == 'undefined') { return null; } + return !this.isParallelTo(obj); + }, + + // Returns the unique intersection with the argument, if one exists. The result + // will be a vector if a line is supplied, and a line if a plane is supplied. + intersectionWith: function(obj) { + if (!this.intersects(obj)) { return null; } + if (obj.direction) { + // obj is a line + var A = obj.anchor.elements, D = obj.direction.elements, + P = this.anchor.elements, N = this.normal.elements; + var multiplier = (N[0]*(P[0]-A[0]) + N[1]*(P[1]-A[1]) + N[2]*(P[2]-A[2])) / (N[0]*D[0] + N[1]*D[1] + N[2]*D[2]); + return Vector.create([A[0] + D[0]*multiplier, A[1] + D[1]*multiplier, A[2] + D[2]*multiplier]); + } else if (obj.normal) { + // obj is a plane + var direction = this.normal.cross(obj.normal).toUnitVector(); + // To find an anchor point, we find one co-ordinate that has a value + // of zero somewhere on the intersection, and remember which one we picked + var N = this.normal.elements, A = this.anchor.elements, + O = obj.normal.elements, B = obj.anchor.elements; + var solver = Matrix.Zero(2,2), i = 0; + while (solver.isSingular()) { + i++; + solver = Matrix.create([ + [ N[i%3], N[(i+1)%3] ], + [ O[i%3], O[(i+1)%3] ] + ]); + } + // Then we solve the simultaneous equations in the remaining dimensions + var inverse = solver.inverse().elements; + var x = N[0]*A[0] + N[1]*A[1] + N[2]*A[2]; + var y = O[0]*B[0] + O[1]*B[1] + O[2]*B[2]; + var intersection = [ + inverse[0][0] * x + inverse[0][1] * y, + inverse[1][0] * x + inverse[1][1] * y + ]; + var anchor = []; + for (var j = 1; j <= 3; j++) { + // This formula picks the right element from intersection by + // cycling depending on which element we set to zero above + anchor.push((i == j) ? 0 : intersection[(j + (5 - i)%3)%3]); + } + return Line.create(anchor, direction); + } + }, + + // Returns the point in the plane closest to the given point + pointClosestTo: function(point) { + var P = point.elements || point; + var A = this.anchor.elements, N = this.normal.elements; + var dot = (A[0] - P[0]) * N[0] + (A[1] - P[1]) * N[1] + (A[2] - (P[2] || 0)) * N[2]; + return Vector.create([P[0] + N[0] * dot, P[1] + N[1] * dot, (P[2] || 0) + N[2] * dot]); + }, + + // Returns a copy of the plane, rotated by t radians about the given line + // See notes on Line#rotate. + rotate: function(t, line) { + var R = t.determinant ? t.elements : Matrix.Rotation(t, line.direction).elements; + var C = line.pointClosestTo(this.anchor).elements; + var A = this.anchor.elements, N = this.normal.elements; + var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2]; + var x = A1 - C1, y = A2 - C2, z = A3 - C3; + return Plane.create([ + C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z, + C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z, + C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z + ], [ + R[0][0] * N[0] + R[0][1] * N[1] + R[0][2] * N[2], + R[1][0] * N[0] + R[1][1] * N[1] + R[1][2] * N[2], + R[2][0] * N[0] + R[2][1] * N[1] + R[2][2] * N[2] + ]); + }, + + // Returns the reflection of the plane in the given point, line or plane. + reflectionIn: function(obj) { + if (obj.normal) { + // obj is a plane + var A = this.anchor.elements, N = this.normal.elements; + var A1 = A[0], A2 = A[1], A3 = A[2], N1 = N[0], N2 = N[1], N3 = N[2]; + var newA = this.anchor.reflectionIn(obj).elements; + // Add the plane's normal to its anchor, then mirror that in the other plane + var AN1 = A1 + N1, AN2 = A2 + N2, AN3 = A3 + N3; + var Q = obj.pointClosestTo([AN1, AN2, AN3]).elements; + var newN = [Q[0] + (Q[0] - AN1) - newA[0], Q[1] + (Q[1] - AN2) - newA[1], Q[2] + (Q[2] - AN3) - newA[2]]; + return Plane.create(newA, newN); + } else if (obj.direction) { + // obj is a line + return this.rotate(Math.PI, obj); + } else { + // obj is a point + var P = obj.elements || obj; + return Plane.create(this.anchor.reflectionIn([P[0], P[1], (P[2] || 0)]), this.normal); + } + }, + + // Sets the anchor point and normal to the plane. If three arguments are specified, + // the normal is calculated by assuming the three points should lie in the same plane. + // If only two are sepcified, the second is taken to be the normal. Normal vector is + // normalised before storage. + setVectors: function(anchor, v1, v2) { + anchor = Vector.create(anchor); + anchor = anchor.to3D(); if (anchor === null) { return null; } + v1 = Vector.create(v1); + v1 = v1.to3D(); if (v1 === null) { return null; } + if (typeof(v2) == 'undefined') { + v2 = null; + } else { + v2 = Vector.create(v2); + v2 = v2.to3D(); if (v2 === null) { return null; } + } + var A1 = anchor.elements[0], A2 = anchor.elements[1], A3 = anchor.elements[2]; + var v11 = v1.elements[0], v12 = v1.elements[1], v13 = v1.elements[2]; + var normal, mod; + if (v2 !== null) { + var v21 = v2.elements[0], v22 = v2.elements[1], v23 = v2.elements[2]; + normal = Vector.create([ + (v12 - A2) * (v23 - A3) - (v13 - A3) * (v22 - A2), + (v13 - A3) * (v21 - A1) - (v11 - A1) * (v23 - A3), + (v11 - A1) * (v22 - A2) - (v12 - A2) * (v21 - A1) + ]); + mod = normal.modulus(); + if (mod === 0) { return null; } + normal = Vector.create([normal.elements[0] / mod, normal.elements[1] / mod, normal.elements[2] / mod]); + } else { + mod = Math.sqrt(v11*v11 + v12*v12 + v13*v13); + if (mod === 0) { return null; } + normal = Vector.create([v1.elements[0] / mod, v1.elements[1] / mod, v1.elements[2] / mod]); + } + this.anchor = anchor; + this.normal = normal; + return this; + } +}; + +// Constructor function +Plane.create = function(anchor, v1, v2) { + var P = new Plane(); + return P.setVectors(anchor, v1, v2); +}; + +// X-Y-Z planes +Plane.XY = Plane.create(Vector.Zero(3), Vector.k); +Plane.YZ = Plane.create(Vector.Zero(3), Vector.i); +Plane.ZX = Plane.create(Vector.Zero(3), Vector.j); +Plane.YX = Plane.XY; Plane.ZY = Plane.YZ; Plane.XZ = Plane.ZX; + +// Returns the plane containing the given points (can be arrays as +// well as vectors). If the points are not coplanar, returns null. +Plane.fromPoints = function(points) { + var np = points.length, list = [], i, P, n, N, A, B, C, D, theta, prevN, totalN = Vector.Zero(3); + for (i = 0; i < np; i++) { + P = Vector.create(points[i]).to3D(); + if (P === null) { return null; } + list.push(P); + n = list.length; + if (n > 2) { + // Compute plane normal for the latest three points + A = list[n-1].elements; B = list[n-2].elements; C = list[n-3].elements; + N = Vector.create([ + (A[1] - B[1]) * (C[2] - B[2]) - (A[2] - B[2]) * (C[1] - B[1]), + (A[2] - B[2]) * (C[0] - B[0]) - (A[0] - B[0]) * (C[2] - B[2]), + (A[0] - B[0]) * (C[1] - B[1]) - (A[1] - B[1]) * (C[0] - B[0]) + ]).toUnitVector(); + if (n > 3) { + // If the latest normal is not (anti)parallel to the previous one, we've strayed off the plane. + // This might be a slightly long-winded way of doing things, but we need the sum of all the normals + // to find which way the plane normal should point so that the points form an anticlockwise list. + theta = N.angleFrom(prevN); + if (theta !== null) { + if (!(Math.abs(theta) <= Sylvester.precision || Math.abs(theta - Math.PI) <= Sylvester.precision)) { return null; } + } + } + totalN = totalN.add(N); + prevN = N; + } + } + // We need to add in the normals at the start and end points, which the above misses out + A = list[1].elements; B = list[0].elements; C = list[n-1].elements; D = list[n-2].elements; + totalN = totalN.add(Vector.create([ + (A[1] - B[1]) * (C[2] - B[2]) - (A[2] - B[2]) * (C[1] - B[1]), + (A[2] - B[2]) * (C[0] - B[0]) - (A[0] - B[0]) * (C[2] - B[2]), + (A[0] - B[0]) * (C[1] - B[1]) - (A[1] - B[1]) * (C[0] - B[0]) + ]).toUnitVector()).add(Vector.create([ + (B[1] - C[1]) * (D[2] - C[2]) - (B[2] - C[2]) * (D[1] - C[1]), + (B[2] - C[2]) * (D[0] - C[0]) - (B[0] - C[0]) * (D[2] - C[2]), + (B[0] - C[0]) * (D[1] - C[1]) - (B[1] - C[1]) * (D[0] - C[0]) + ]).toUnitVector()); + return Plane.create(list[0], totalN); +}; + +module.exports = Plane; + +},{"./line":13,"./matrix":15,"./sylvester":17,"./vector":18}],17:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// This file is required in order for any other classes to work. Some Vector methods work with the +// other Sylvester classes and are useless unless they are included. Other classes such as Line and +// Plane will not function at all without Vector being loaded first. + +Math.sign = function(x) { + return x < 0 ? -1: 1; +} + +var Sylvester = { + precision: 1e-6, + approxPrecision: 1e-5 +}; + +module.exports = Sylvester; + +},{}],18:[function(require,module,exports){ +// Copyright (c) 2011, Chris Umbel, James Coglan +// This file is required in order for any other classes to work. Some Vector methods work with the +// other Sylvester classes and are useless unless they are included. Other classes such as Line and +// Plane will not function at all without Vector being loaded first. + +var Sylvester = require('./sylvester'), +Matrix = require('./matrix'); + +function Vector() {} +Vector.prototype = { + + norm: function() { + var n = this.elements.length; + var sum = 0; + + while (n--) { + sum += Math.pow(this.elements[n], 2); + } + + return Math.sqrt(sum); + }, + + // Returns element i of the vector + e: function(i) { + return (i < 1 || i > this.elements.length) ? null : this.elements[i - 1]; + }, + + // Returns the number of rows/columns the vector has + dimensions: function() { + return {rows: 1, cols: this.elements.length}; + }, + + // Returns the number of rows in the vector + rows: function() { + return 1; + }, + + // Returns the number of columns in the vector + cols: function() { + return this.elements.length; + }, + + // Returns the modulus ('length') of the vector + modulus: function() { + return Math.sqrt(this.dot(this)); + }, + + // Returns true iff the vector is equal to the argument + eql: function(vector) { + var n = this.elements.length; + var V = vector.elements || vector; + if (n != V.length) { return false; } + while (n--) { + if (Math.abs(this.elements[n] - V[n]) > Sylvester.precision) { return false; } + } + return true; + }, + + // Returns a copy of the vector + dup: function() { + return Vector.create(this.elements); + }, + + // Maps the vector to another vector according to the given function + map: function(fn) { + var elements = []; + this.each(function(x, i) { + elements.push(fn(x, i)); + }); + return Vector.create(elements); + }, + + // Calls the iterator for each element of the vector in turn + each: function(fn) { + var n = this.elements.length; + for (var i = 0; i < n; i++) { + fn(this.elements[i], i + 1); + } + }, + + // Returns a new vector created by normalizing the receiver + toUnitVector: function() { + var r = this.modulus(); + if (r === 0) { return this.dup(); } + return this.map(function(x) { return x / r; }); + }, + + // Returns the angle between the vector and the argument (also a vector) + angleFrom: function(vector) { + var V = vector.elements || vector; + var n = this.elements.length, k = n, i; + if (n != V.length) { return null; } + var dot = 0, mod1 = 0, mod2 = 0; + // Work things out in parallel to save time + this.each(function(x, i) { + dot += x * V[i - 1]; + mod1 += x * x; + mod2 += V[i - 1] * V[i - 1]; + }); + mod1 = Math.sqrt(mod1); mod2 = Math.sqrt(mod2); + if (mod1 * mod2 === 0) { return null; } + var theta = dot / (mod1 * mod2); + if (theta < -1) { theta = -1; } + if (theta > 1) { theta = 1; } + return Math.acos(theta); + }, + + // Returns true iff the vector is parallel to the argument + isParallelTo: function(vector) { + var angle = this.angleFrom(vector); + return (angle === null) ? null : (angle <= Sylvester.precision); + }, + + // Returns true iff the vector is antiparallel to the argument + isAntiparallelTo: function(vector) { + var angle = this.angleFrom(vector); + return (angle === null) ? null : (Math.abs(angle - Math.PI) <= Sylvester.precision); + }, + + // Returns true iff the vector is perpendicular to the argument + isPerpendicularTo: function(vector) { + var dot = this.dot(vector); + return (dot === null) ? null : (Math.abs(dot) <= Sylvester.precision); + }, + + // Returns the result of adding the argument to the vector + add: function(value) { + var V = value.elements || value; + + if (this.elements.length != V.length) + return this.map(function(v) { return v + value }); + else + return this.map(function(x, i) { return x + V[i - 1]; }); + }, + + // Returns the result of subtracting the argument from the vector + subtract: function(v) { + if (typeof(v) == 'number') + return this.map(function(k) { return k - v; }); + + var V = v.elements || v; + if (this.elements.length != V.length) { return null; } + return this.map(function(x, i) { return x - V[i - 1]; }); + }, + + // Returns the result of multiplying the elements of the vector by the argument + multiply: function(k) { + return this.map(function(x) { return x * k; }); + }, + + elementMultiply: function(v) { + return this.map(function(k, i) { + return v.e(i) * k; + }); + }, + + sum: function() { + var sum = 0; + this.map(function(x) { sum += x;}); + return sum; + }, + + chomp: function(n) { + var elements = []; + + for (var i = n; i < this.elements.length; i++) { + elements.push(this.elements[i]); + } + + return Vector.create(elements); + }, + + top: function(n) { + var elements = []; + + for (var i = 0; i < n; i++) { + elements.push(this.elements[i]); + } + + return Vector.create(elements); + }, + + augment: function(elements) { + var newElements = this.elements; + + for (var i = 0; i < elements.length; i++) { + newElements.push(elements[i]); + } + + return Vector.create(newElements); + }, + + x: function(k) { return this.multiply(k); }, + + log: function() { + return Vector.log(this); + }, + + elementDivide: function(vector) { + return this.map(function(v, i) { + return v / vector.e(i); + }); + }, + + product: function() { + var p = 1; + + this.map(function(v) { + p *= v; + }); + + return p; + }, + + // Returns the scalar product of the vector with the argument + // Both vectors must have equal dimensionality + dot: function(vector) { + var V = vector.elements || vector; + var i, product = 0, n = this.elements.length; + if (n != V.length) { return null; } + while (n--) { product += this.elements[n] * V[n]; } + return product; + }, + + // Returns the vector product of the vector with the argument + // Both vectors must have dimensionality 3 + cross: function(vector) { + var B = vector.elements || vector; + if (this.elements.length != 3 || B.length != 3) { return null; } + var A = this.elements; + return Vector.create([ + (A[1] * B[2]) - (A[2] * B[1]), + (A[2] * B[0]) - (A[0] * B[2]), + (A[0] * B[1]) - (A[1] * B[0]) + ]); + }, + + // Returns the (absolute) largest element of the vector + max: function() { + var m = 0, i = this.elements.length; + while (i--) { + if (Math.abs(this.elements[i]) > Math.abs(m)) { m = this.elements[i]; } + } + return m; + }, + + + maxIndex: function() { + var m = 0, i = this.elements.length; + var maxIndex = -1; + + while (i--) { + if (Math.abs(this.elements[i]) > Math.abs(m)) { + m = this.elements[i]; + maxIndex = i + 1; + } + } + + return maxIndex; + }, + + + // Returns the index of the first match found + indexOf: function(x) { + var index = null, n = this.elements.length; + for (var i = 0; i < n; i++) { + if (index === null && this.elements[i] == x) { + index = i + 1; + } + } + return index; + }, + + // Returns a diagonal matrix with the vector's elements as its diagonal elements + toDiagonalMatrix: function() { + return Matrix.Diagonal(this.elements); + }, + + // Returns the result of rounding the elements of the vector + round: function() { + return this.map(function(x) { return Math.round(x); }); + }, + + // Transpose a Vector, return a 1xn Matrix + transpose: function() { + var rows = this.elements.length; + var elements = []; + + for (var i = 0; i < rows; i++) { + elements.push([this.elements[i]]); + } + return Matrix.create(elements); + }, + + // Returns a copy of the vector with elements set to the given value if they + // differ from it by less than Sylvester.precision + snapTo: function(x) { + return this.map(function(y) { + return (Math.abs(y - x) <= Sylvester.precision) ? x : y; + }); + }, + + // Returns the vector's distance from the argument, when considered as a point in space + distanceFrom: function(obj) { + if (obj.anchor || (obj.start && obj.end)) { return obj.distanceFrom(this); } + var V = obj.elements || obj; + if (V.length != this.elements.length) { return null; } + var sum = 0, part; + this.each(function(x, i) { + part = x - V[i - 1]; + sum += part * part; + }); + return Math.sqrt(sum); + }, + + // Returns true if the vector is point on the given line + liesOn: function(line) { + return line.contains(this); + }, + + // Return true iff the vector is a point in the given plane + liesIn: function(plane) { + return plane.contains(this); + }, + + // Rotates the vector about the given object. The object should be a + // point if the vector is 2D, and a line if it is 3D. Be careful with line directions! + rotate: function(t, obj) { + var V, R = null, x, y, z; + if (t.determinant) { R = t.elements; } + switch (this.elements.length) { + case 2: + V = obj.elements || obj; + if (V.length != 2) { return null; } + if (!R) { R = Matrix.Rotation(t).elements; } + x = this.elements[0] - V[0]; + y = this.elements[1] - V[1]; + return Vector.create([ + V[0] + R[0][0] * x + R[0][1] * y, + V[1] + R[1][0] * x + R[1][1] * y + ]); + break; + case 3: + if (!obj.direction) { return null; } + var C = obj.pointClosestTo(this).elements; + if (!R) { R = Matrix.Rotation(t, obj.direction).elements; } + x = this.elements[0] - C[0]; + y = this.elements[1] - C[1]; + z = this.elements[2] - C[2]; + return Vector.create([ + C[0] + R[0][0] * x + R[0][1] * y + R[0][2] * z, + C[1] + R[1][0] * x + R[1][1] * y + R[1][2] * z, + C[2] + R[2][0] * x + R[2][1] * y + R[2][2] * z + ]); + break; + default: + return null; + } + }, + + // Returns the result of reflecting the point in the given point, line or plane + reflectionIn: function(obj) { + if (obj.anchor) { + // obj is a plane or line + var P = this.elements.slice(); + var C = obj.pointClosestTo(P).elements; + return Vector.create([C[0] + (C[0] - P[0]), C[1] + (C[1] - P[1]), C[2] + (C[2] - (P[2] || 0))]); + } else { + // obj is a point + var Q = obj.elements || obj; + if (this.elements.length != Q.length) { return null; } + return this.map(function(x, i) { return Q[i - 1] + (Q[i - 1] - x); }); + } + }, + + // Utility to make sure vectors are 3D. If they are 2D, a zero z-component is added + to3D: function() { + var V = this.dup(); + switch (V.elements.length) { + case 3: break; + case 2: V.elements.push(0); break; + default: return null; + } + return V; + }, + + // Returns a string representation of the vector + inspect: function() { + return '[' + this.elements.join(', ') + ']'; + }, + + // Set vector's elements from an array + setElements: function(els) { + this.elements = (els.elements || els).slice(); + return this; + } +}; + +// Constructor function +Vector.create = function(elements) { + var V = new Vector(); + return V.setElements(elements); +}; + +// i, j, k unit vectors +Vector.i = Vector.create([1, 0, 0]); +Vector.j = Vector.create([0, 1, 0]); +Vector.k = Vector.create([0, 0, 1]); + +// Random vector of size n +Vector.Random = function(n) { + var elements = []; + while (n--) { elements.push(Math.random()); } + return Vector.create(elements); +}; + +Vector.Fill = function(n, v) { + var elements = []; + while (n--) { elements.push(v); } + return Vector.create(elements); +}; + +// Vector filled with zeros +Vector.Zero = function(n) { + return Vector.Fill(n, 0); +}; + +Vector.One = function(n) { + return Vector.Fill(n, 1); +}; + +Vector.log = function(v) { + return v.map(function(x) { + return Math.log(x); + }); +}; + +module.exports = Vector; + +},{"./matrix":15,"./sylvester":17}],19:[function(require,module,exports){ +"use strict"; + +/** + * Represents a 2-dimensional size value. + */ + +function Size(w, h) { + this.w = w; + this.h = h; +} + +Size.prototype = { + toString: function () { + return "(" + this.w + ", " + this.h + ")"; + }, + getHalfSize: function() { + return new Size(this.w >>> 1, this.h >>> 1); + }, + length: function() { + return this.w * this.h; + } +} +module.exports = Size; +},{}],20:[function(require,module,exports){ +"use strict"; + +var error = require('./error'); + +function assert(condition, message) { + if (!condition) { + error(message); + } +} + + +module.exports = assert; + +},{"./error":21}],21:[function(require,module,exports){ +"use strict"; + +function error(message) { + console.error(message); + console.trace(); +} + +module.exports = error; + +},{}],22:[function(require,module,exports){ +"use strict"; + +var Matrix = require('sylvester.js').Matrix; +var Vector = require('sylvester.js').Vector; +var $M = Matrix.create; + + +// augment Sylvester some +Matrix.Translation = function (v) +{ + if (v.elements.length == 2) { + var r = Matrix.I(3); + r.elements[2][0] = v.elements[0]; + r.elements[2][1] = v.elements[1]; + return r; + } + + if (v.elements.length == 3) { + var r = Matrix.I(4); + r.elements[0][3] = v.elements[0]; + r.elements[1][3] = v.elements[1]; + r.elements[2][3] = v.elements[2]; + return r; + } + + throw "Invalid length for Translation"; +} + +Matrix.prototype.flatten = function () +{ + var result = []; + if (this.elements.length == 0) + return []; + + + for (var j = 0; j < this.elements[0].length; j++) + for (var i = 0; i < this.elements.length; i++) + result.push(this.elements[i][j]); + return result; +} + +Matrix.prototype.ensure4x4 = function() +{ + if (this.elements.length == 4 && + this.elements[0].length == 4) + return this; + + if (this.elements.length > 4 || + this.elements[0].length > 4) + return null; + + for (var i = 0; i < this.elements.length; i++) { + for (var j = this.elements[i].length; j < 4; j++) { + if (i == j) + this.elements[i].push(1); + else + this.elements[i].push(0); + } + } + + for (var i = this.elements.length; i < 4; i++) { + if (i == 0) + this.elements.push([1, 0, 0, 0]); + else if (i == 1) + this.elements.push([0, 1, 0, 0]); + else if (i == 2) + this.elements.push([0, 0, 1, 0]); + else if (i == 3) + this.elements.push([0, 0, 0, 1]); + } + + return this; +}; + + +Vector.prototype.flatten = function () +{ + return this.elements; +}; + + + +// +// gluPerspective +// +function makePerspective(fovy, aspect, znear, zfar) +{ + var ymax = znear * Math.tan(fovy * Math.PI / 360.0); + var ymin = -ymax; + var xmin = ymin * aspect; + var xmax = ymax * aspect; + + return makeFrustum(xmin, xmax, ymin, ymax, znear, zfar); +} + +// +// glFrustum +// +function makeFrustum(left, right, + bottom, top, + znear, zfar) +{ + var X = 2*znear/(right-left); + var Y = 2*znear/(top-bottom); + var A = (right+left)/(right-left); + var B = (top+bottom)/(top-bottom); + var C = -(zfar+znear)/(zfar-znear); + var D = -2*zfar*znear/(zfar-znear); + + return $M([[X, 0, A, 0], + [0, Y, B, 0], + [0, 0, C, D], + [0, 0, -1, 0]]); +} + +module.exports.makePerspective = makePerspective; + + +},{"sylvester.js":12}],23:[function(require,module,exports){ +"use strict"; + +var Avc = require('../broadway/Decoder'); +var YUVWebGLCanvas = require('../canvas/YUVWebGLCanvas'); +var YUVCanvas = require('../canvas/YUVCanvas'); +var Size = require('../utils/Size'); +var Class = require('uclass'); +var Events = require('uclass/events'); +var debug = require('debug'); +var log = console.log; + +var WSAvcPlayer = new Class({ + Implements : [Events], + + + initialize : function(canvas, canvastype) { + + this.canvas = canvas; + this.canvastype = canvastype; + + // AVC codec initialization + this.avc = new Avc(); + if(false) this.avc.configure({ + filter: "original", + filterHorLuma: "optimized", + filterVerLumaEdge: "optimized", + getBoundaryStrengthsA: "optimized" + }); + + //WebSocket variable + this.ws; + this.pktnum = 0; + + }, + + + decode : function(data) { + var naltype = "invalid frame"; + + if (data.length > 4) { + if (data[4] == 0x65) { + naltype = "I frame"; + } + else if (data[4] == 0x41) { + naltype = "P frame"; + } + else if (data[4] == 0x67) { + naltype = "SPS"; + } + else if (data[4] == 0x68) { + naltype = "PPS"; + } + } + //log("Passed " + naltype + " to decoder"); + this.avc.decode(data); + }, + + connect : function(url) { + var framesList = []; + this.write = function(data){ + this.pktnum++; + var frame = new Uint8Array(data); + //log("[Pkt " + this.pktnum + " (" + data.byteLength + " bytes)]"); + //this.decode(frame); + framesList.push(frame); + } + var running = true; + + var shiftFrame = function() { + if(!running) + return; + + + if(framesList.length > 10) { + log("Dropping frames", framesList.length); + framesList.splice(0,10); + } + + var frame = framesList.shift(); + + + if(frame) + this.decode(frame); + + requestAnimationFrame(shiftFrame); + }.bind(this); + + + shiftFrame(); + }, + + initCanvas : function(width, height) { + var canvasFactory = this.canvastype == "webgl" || this.canvastype == "YUVWebGLCanvas" + ? YUVWebGLCanvas + : YUVCanvas; + + var canvas = new canvasFactory(this.canvas, new Size(width, height)); + this.avc.onPictureDecoded = canvas.decode; + this.emit("canvasReady", width, height); + }, + + cmd : function(cmd){ + log("Incoming request", cmd); + + if(cmd.action == "init") { + this.initCanvas(cmd.width, cmd.height); + this.canvas.width = cmd.width; + this.canvas.height = cmd.height; + } + }, + + disconnect : function() { +// this.ws.close(); + }, + + playStream : function() { + var message = "REQUESTSTREAM "; +// this.ws.send(message); + log("Sent " + message); + }, + + + stopStream : function() { + this.ws.send("STOPSTREAM"); + log("Sent STOPSTREAM"); + }, +}); + + +module.exports = WSAvcPlayer; +module.exports.debug = debug; + +},{"../broadway/Decoder":4,"../canvas/YUVCanvas":10,"../canvas/YUVWebGLCanvas":11,"../utils/Size":19,"debug":1,"uclass":47,"uclass/events":24}],24:[function(require,module,exports){ +"use strict"; + +var Class = require('../'); +var guid = require('mout/random/guid'); +var forIn = require('mout/object/forIn'); + +var EventEmitter = new Class({ + Binds : ['on', 'off', 'once', 'emit'], + + callbacks : {}, + + initialize : function() { + var self = this; + this.addEvent = this.on; + this.removeListener = this.off; + this.removeAllListeners = this.off; + this.fireEvent = this.emit; + }, + + emit:function(event, payload){ + if(!this.callbacks[event]) + return; + + var args = Array.prototype.slice.call(arguments, 1); + + forIn(this.callbacks[event], function(callback){ + callback.apply(null, args); + }); + }, + + + on:function(event, callback){ + if(typeof callback != "function") + return console.log("you try to register a non function in " , event) + if(!this.callbacks[event]) + this.callbacks[event] = {}; + this.callbacks[event][guid()] = callback; + }, + + once:function(event, callback){ + var self = this; + var once = function(){ + self.off(event, once); + self.off(event, callback); + }; + + this.on(event, callback); + this.on(event, once); + }, + + off:function(event, callback){ + if(!event) + this.callbacks = {}; + else if(!callback) + this.callbacks[event] = {}; + else forIn(this.callbacks[event] || {}, function(v, k) { + if(v == callback) + delete this.callbacks[event][k]; + }, this); + }, +}); + +module.exports = EventEmitter; +},{"../":47,"mout/object/forIn":36,"mout/random/guid":42}],25:[function(require,module,exports){ +"use strict"; + +var verbs = /^Implements|Extends|Binds$/ + +module.exports = function(ctx, obj){ + for(var key in obj) { + if(key.match(verbs)) continue; + if((typeof obj[key] == 'function') && obj[key].$static) + ctx[key] = obj[key]; + else + ctx.prototype[key] = obj[key]; + } + return ctx; +} +},{}],26:[function(require,module,exports){ +var kindOf = require('./kindOf'); +var isPlainObject = require('./isPlainObject'); +var mixIn = require('../object/mixIn'); + + /** + * Clone native types. + */ + function clone(val){ + switch (kindOf(val)) { + case 'Object': + return cloneObject(val); + case 'Array': + return cloneArray(val); + case 'RegExp': + return cloneRegExp(val); + case 'Date': + return cloneDate(val); + default: + return val; + } + } + + function cloneObject(source) { + if (isPlainObject(source)) { + return mixIn({}, source); + } else { + return source; + } + } + + function cloneRegExp(r) { + var flags = ''; + flags += r.multiline ? 'm' : ''; + flags += r.global ? 'g' : ''; + flags += r.ignoreCase ? 'i' : ''; + return new RegExp(r.source, flags); + } + + function cloneDate(date) { + return new Date(+date); + } + + function cloneArray(arr) { + return arr.slice(); + } + + module.exports = clone; + + + +},{"../object/mixIn":40,"./isPlainObject":32,"./kindOf":33}],27:[function(require,module,exports){ +var mixIn = require('../object/mixIn'); + + /** + * Create Object using prototypal inheritance and setting custom properties. + * - Mix between Douglas Crockford Prototypal Inheritance and the EcmaScript 5 `Object.create()` method. + * @param {object} parent Parent Object. + * @param {object} [props] Object properties. + * @return {object} Created object. + */ + function createObject(parent, props){ + function F(){} + F.prototype = parent; + return mixIn(new F(), props); + + } + module.exports = createObject; + + + +},{"../object/mixIn":40}],28:[function(require,module,exports){ +var clone = require('./clone'); +var forOwn = require('../object/forOwn'); +var kindOf = require('./kindOf'); +var isPlainObject = require('./isPlainObject'); + + /** + * Recursively clone native types. + */ + function deepClone(val, instanceClone) { + switch ( kindOf(val) ) { + case 'Object': + return cloneObject(val, instanceClone); + case 'Array': + return cloneArray(val, instanceClone); + default: + return clone(val); + } + } + + function cloneObject(source, instanceClone) { + if (isPlainObject(source)) { + var out = {}; + forOwn(source, function(val, key) { + this[key] = deepClone(val, instanceClone); + }, out); + return out; + } else if (instanceClone) { + return instanceClone(source); + } else { + return source; + } + } + + function cloneArray(arr, instanceClone) { + var out = [], + i = -1, + n = arr.length, + val; + while (++i < n) { + out[i] = deepClone(arr[i], instanceClone); + } + return out; + } + + module.exports = deepClone; + + + + +},{"../object/forOwn":37,"./clone":26,"./isPlainObject":32,"./kindOf":33}],29:[function(require,module,exports){ +var isKind = require('./isKind'); + /** + */ + var isArray = Array.isArray || function (val) { + return isKind(val, 'Array'); + }; + module.exports = isArray; + + +},{"./isKind":30}],30:[function(require,module,exports){ +var kindOf = require('./kindOf'); + /** + * Check if value is from a specific "kind". + */ + function isKind(val, kind){ + return kindOf(val) === kind; + } + module.exports = isKind; + + +},{"./kindOf":33}],31:[function(require,module,exports){ +var isKind = require('./isKind'); + /** + */ + function isObject(val) { + return isKind(val, 'Object'); + } + module.exports = isObject; + + +},{"./isKind":30}],32:[function(require,module,exports){ + + + /** + * Checks if the value is created by the `Object` constructor. + */ + function isPlainObject(value) { + return (!!value && typeof value === 'object' && + value.constructor === Object); + } + + module.exports = isPlainObject; + + + +},{}],33:[function(require,module,exports){ + + + var _rKind = /^\[object (.*)\]$/, + _toString = Object.prototype.toString, + UNDEF; + + /** + * Gets the "kind" of value. (e.g. "String", "Number", etc) + */ + function kindOf(val) { + if (val === null) { + return 'Null'; + } else if (val === UNDEF) { + return 'Undefined'; + } else { + return _rKind.exec( _toString.call(val) )[1]; + } + } + module.exports = kindOf; + + +},{}],34:[function(require,module,exports){ +/** + * @constant Maximum 32-bit signed integer value. (2^31 - 1) + */ + + module.exports = 2147483647; + + +},{}],35:[function(require,module,exports){ +/** + * @constant Minimum 32-bit signed integer value (-2^31). + */ + + module.exports = -2147483648; + + +},{}],36:[function(require,module,exports){ +var hasOwn = require('./hasOwn'); + + var _hasDontEnumBug, + _dontEnums; + + function checkDontEnum(){ + _dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' + ]; + + _hasDontEnumBug = true; + + for (var key in {'toString': null}) { + _hasDontEnumBug = false; + } + } + + /** + * Similar to Array/forEach but works over object properties and fixes Don't + * Enum bug on IE. + * based on: http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation + */ + function forIn(obj, fn, thisObj){ + var key, i = 0; + // no need to check if argument is a real object that way we can use + // it for arrays, functions, date, etc. + + //post-pone check till needed + if (_hasDontEnumBug == null) checkDontEnum(); + + for (key in obj) { + if (exec(fn, obj, key, thisObj) === false) { + break; + } + } + + + if (_hasDontEnumBug) { + var ctor = obj.constructor, + isProto = !!ctor && obj === ctor.prototype; + + while (key = _dontEnums[i++]) { + // For constructor, if it is a prototype object the constructor + // is always non-enumerable unless defined otherwise (and + // enumerated above). For non-prototype objects, it will have + // to be defined on this object, since it cannot be defined on + // any prototype objects. + // + // For other [[DontEnum]] properties, check if the value is + // different than Object prototype value. + if ( + (key !== 'constructor' || + (!isProto && hasOwn(obj, key))) && + obj[key] !== Object.prototype[key] + ) { + if (exec(fn, obj, key, thisObj) === false) { + break; + } + } + } + } + } + + function exec(fn, obj, key, thisObj){ + return fn.call(thisObj, obj[key], key, obj); + } + + module.exports = forIn; + + + +},{"./hasOwn":38}],37:[function(require,module,exports){ +var hasOwn = require('./hasOwn'); +var forIn = require('./forIn'); + + /** + * Similar to Array/forEach but works over object properties and fixes Don't + * Enum bug on IE. + * based on: http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation + */ + function forOwn(obj, fn, thisObj){ + forIn(obj, function(val, key){ + if (hasOwn(obj, key)) { + return fn.call(thisObj, obj[key], key, obj); + } + }); + } + + module.exports = forOwn; + + + +},{"./forIn":36,"./hasOwn":38}],38:[function(require,module,exports){ + + + /** + * Safer Object.hasOwnProperty + */ + function hasOwn(obj, prop){ + return Object.prototype.hasOwnProperty.call(obj, prop); + } + + module.exports = hasOwn; + + + +},{}],39:[function(require,module,exports){ +var hasOwn = require('./hasOwn'); +var deepClone = require('../lang/deepClone'); +var isObject = require('../lang/isObject'); + + /** + * Deep merge objects. + */ + function merge() { + var i = 1, + key, val, obj, target; + + // make sure we don't modify source element and it's properties + // objects are passed by reference + target = deepClone( arguments[0] ); + + while (obj = arguments[i++]) { + for (key in obj) { + if ( ! hasOwn(obj, key) ) { + continue; + } + + val = obj[key]; + + if ( isObject(val) && isObject(target[key]) ){ + // inception, deep merge objects + target[key] = merge(target[key], val); + } else { + // make sure arrays, regexp, date, objects are cloned + target[key] = deepClone(val); + } + + } + } + + return target; + } + + module.exports = merge; + + + +},{"../lang/deepClone":28,"../lang/isObject":31,"./hasOwn":38}],40:[function(require,module,exports){ +var forOwn = require('./forOwn'); + + /** + * Combine properties from all the objects into first one. + * - This method affects target object in place, if you want to create a new Object pass an empty object as first param. + * @param {object} target Target Object + * @param {...object} objects Objects to be combined (0...n objects). + * @return {object} Target Object. + */ + function mixIn(target, objects){ + var i = 0, + n = arguments.length, + obj; + while(++i < n){ + obj = arguments[i]; + if (obj != null) { + forOwn(obj, copyProp, target); + } + } + return target; + } + + function copyProp(val, key){ + this[key] = val; + } + + module.exports = mixIn; + + +},{"./forOwn":37}],41:[function(require,module,exports){ +var randInt = require('./randInt'); +var isArray = require('../lang/isArray'); + + /** + * Returns a random element from the supplied arguments + * or from the array (if single argument is an array). + */ + function choice(items) { + var target = (arguments.length === 1 && isArray(items))? items : arguments; + return target[ randInt(0, target.length - 1) ]; + } + + module.exports = choice; + + + +},{"../lang/isArray":29,"./randInt":45}],42:[function(require,module,exports){ +var randHex = require('./randHex'); +var choice = require('./choice'); + + /** + * Returns pseudo-random guid (UUID v4) + * IMPORTANT: it's not totally "safe" since randHex/choice uses Math.random + * by default and sequences can be predicted in some cases. See the + * "random/random" documentation for more info about it and how to replace + * the default PRNG. + */ + function guid() { + return ( + randHex(8)+'-'+ + randHex(4)+'-'+ + // v4 UUID always contain "4" at this position to specify it was + // randomly generated + '4' + randHex(3) +'-'+ + // v4 UUID always contain chars [a,b,8,9] at this position + choice(8, 9, 'a', 'b') + randHex(3)+'-'+ + randHex(12) + ); + } + module.exports = guid; + + +},{"./choice":41,"./randHex":44}],43:[function(require,module,exports){ +var random = require('./random'); +var MIN_INT = require('../number/MIN_INT'); +var MAX_INT = require('../number/MAX_INT'); + + /** + * Returns random number inside range + */ + function rand(min, max){ + min = min == null? MIN_INT : min; + max = max == null? MAX_INT : max; + return min + (max - min) * random(); + } + + module.exports = rand; + + +},{"../number/MAX_INT":34,"../number/MIN_INT":35,"./random":46}],44:[function(require,module,exports){ +var choice = require('./choice'); + + var _chars = '0123456789abcdef'.split(''); + + /** + * Returns a random hexadecimal string + */ + function randHex(size){ + size = size && size > 0? size : 6; + var str = ''; + while (size--) { + str += choice(_chars); + } + return str; + } + + module.exports = randHex; + + + +},{"./choice":41}],45:[function(require,module,exports){ +var MIN_INT = require('../number/MIN_INT'); +var MAX_INT = require('../number/MAX_INT'); +var rand = require('./rand'); + + /** + * Gets random integer inside range or snap to min/max values. + */ + function randInt(min, max){ + min = min == null? MIN_INT : ~~min; + max = max == null? MAX_INT : ~~max; + // can't be max + 0.5 otherwise it will round up if `rand` + // returns `max` causing it to overflow range. + // -0.5 and + 0.49 are required to avoid bias caused by rounding + return Math.round( rand(min - 0.5, max + 0.499999999999) ); + } + + module.exports = randInt; + + +},{"../number/MAX_INT":34,"../number/MIN_INT":35,"./rand":43}],46:[function(require,module,exports){ + + + /** + * Just a wrapper to Math.random. No methods inside mout/random should call + * Math.random() directly so we can inject the pseudo-random number + * generator if needed (ie. in case we need a seeded random or a better + * algorithm than the native one) + */ + function random(){ + return random.get(); + } + + // we expose the method so it can be swapped if needed + random.get = Math.random; + + module.exports = random; + + + +},{}],47:[function(require,module,exports){ +"use strict"; + +var hasOwn = require("mout/object/hasOwn"); +var create = require("mout/lang/createObject"); +var merge = require("mout/object/merge"); +var kindOf = require("mout/lang/kindOf"); +var mixIn = require("mout/object/mixIn"); + +var implement = require('./implement'); +var verbs = /^Implements|Extends|Binds$/ + + + + +var uClass = function(proto){ + + if(kindOf(proto) === "Function") proto = {initialize: proto}; + + var superprime = proto.Extends; + + var constructor = (hasOwn(proto, "initialize")) ? proto.initialize : superprime ? superprime : function(){}; + + + + var out = function() { + var self = this; + //autobinding takes place here + if(proto.Binds) proto.Binds.forEach(function(f){ + var original = self[f]; + if(original) + self[f] = mixIn(self[f].bind(self), original); + }); + + //clone non function/static properties to current instance + for(var key in out.prototype) { + var v = out.prototype[key], t = kindOf(v); + + if(key.match(verbs) || t === "Function" || t == "GeneratorFunction") + continue; + + if(t == "Object") + self[key] = merge({}, self[key]); //create(null, self[key]); + else if(t == "Array") + self[key] = v.slice(); //clone ?? + else + self[key] = v; + } + + if(proto.Implements) + proto.Implements.forEach(function(Mixin){ + Mixin.call(self); + }); + + + + + constructor.apply(this, arguments); + } + + + if (superprime) { + // inherit from superprime + var superproto = superprime.prototype; + if(superproto.Binds) + proto.Binds = (proto.Binds || []).concat(superproto.Binds); + + if(superproto.Implements) + proto.Implements = (proto.Implements || []).concat(superproto.Implements); + + var cproto = out.prototype = create(superproto); + // setting constructor.parent to superprime.prototype + // because it's the shortest possible absolute reference + out.parent = superproto; + cproto.constructor = out + + } + + + if(proto.Implements) { + if (kindOf(proto.Implements) !== "Array") + proto.Implements = [proto.Implements]; + proto.Implements.forEach(function(Mixin){ + implement(out, Mixin.prototype); + }); + } + + implement(out, proto); + if(proto.Binds) + out.prototype.Binds = proto.Binds; + if(proto.Implements) + out.prototype.Implements = proto.Implements; + + return out; +}; + + + +module.exports = uClass; +},{"./implement":25,"mout/lang/createObject":27,"mout/lang/kindOf":33,"mout/object/hasOwn":38,"mout/object/merge":39,"mout/object/mixIn":40}]},{},[23])(23) +}); \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/package.json b/tools/ffmpegToWeb/Player/broadway/package.json new file mode 100644 index 0000000..9bcc8b9 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/package.json @@ -0,0 +1,35 @@ +{ + "name": "h264-live-player", + "version": "1.3.1", + "main": "wsavc/index.js", + "scripts": { + "dist": "browserify --bare --standalone WSAvcPlayer --plugin discify wsavc/ > dist/http-live-player.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git@github.com:131/h264-live-player.git" + }, + "keywords": [ + "h264", + "nal", + "live", + "broadcast", + "streaming" + ], + "author": "Francois Leurent <131.js@cloudyks.org>", + "license": "ISC", + "bugs": { + "url": "https://github.com/131/h264-live-player/issues" + }, + "description": "This is a very simple h264 video player (that can run on live stream) for your browser.\r You might use this with raspicam raw h264 stream.\r This is a player around [Broadway](https://github.com/mbebenita/Broadway) Decoder, with very simple API.\r NAL unit (h264 frames) are split on the server side, so the client side is very simple (and allow frame skipping easily)", + "dependencies": { + "debug": "^2.3.2", + "sylvester.js": "^0.1.1", + "uclass": "^2.4.0" + }, + "devDependencies": { + "browserify": "^13.0.0", + "discify": "^1.4.2" + } +} diff --git a/tools/ffmpegToWeb/Player/broadway/utils/Size.js b/tools/ffmpegToWeb/Player/broadway/utils/Size.js new file mode 100644 index 0000000..4b2edfb --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/utils/Size.js @@ -0,0 +1,23 @@ +"use strict"; + +/** + * Represents a 2-dimensional size value. + */ + +function Size(w, h) { + this.w = w; + this.h = h; +} + +Size.prototype = { + toString: function () { + return "(" + this.w + ", " + this.h + ")"; + }, + getHalfSize: function() { + return new Size(this.w >>> 1, this.h >>> 1); + }, + length: function() { + return this.w * this.h; + } +} +module.exports = Size; \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/utils/assert.js b/tools/ffmpegToWeb/Player/broadway/utils/assert.js new file mode 100644 index 0000000..4db14a5 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/utils/assert.js @@ -0,0 +1,12 @@ +"use strict"; + +var error = require('./error'); + +function assert(condition, message) { + if (!condition) { + error(message); + } +} + + +module.exports = assert; diff --git a/tools/ffmpegToWeb/Player/broadway/utils/error.js b/tools/ffmpegToWeb/Player/broadway/utils/error.js new file mode 100644 index 0000000..f3f06f1 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/utils/error.js @@ -0,0 +1,8 @@ +"use strict"; + +function error(message) { + console.error(message); + console.trace(); +} + +module.exports = error; diff --git a/tools/ffmpegToWeb/Player/broadway/utils/glUtils.js b/tools/ffmpegToWeb/Player/broadway/utils/glUtils.js new file mode 100644 index 0000000..53d0160 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/utils/glUtils.js @@ -0,0 +1,117 @@ +"use strict"; + +var Matrix = require('sylvester.js').Matrix; +var Vector = require('sylvester.js').Vector; +var $M = Matrix.create; + + +// augment Sylvester some +Matrix.Translation = function (v) +{ + if (v.elements.length == 2) { + var r = Matrix.I(3); + r.elements[2][0] = v.elements[0]; + r.elements[2][1] = v.elements[1]; + return r; + } + + if (v.elements.length == 3) { + var r = Matrix.I(4); + r.elements[0][3] = v.elements[0]; + r.elements[1][3] = v.elements[1]; + r.elements[2][3] = v.elements[2]; + return r; + } + + throw "Invalid length for Translation"; +} + +Matrix.prototype.flatten = function () +{ + var result = []; + if (this.elements.length == 0) + return []; + + + for (var j = 0; j < this.elements[0].length; j++) + for (var i = 0; i < this.elements.length; i++) + result.push(this.elements[i][j]); + return result; +} + +Matrix.prototype.ensure4x4 = function() +{ + if (this.elements.length == 4 && + this.elements[0].length == 4) + return this; + + if (this.elements.length > 4 || + this.elements[0].length > 4) + return null; + + for (var i = 0; i < this.elements.length; i++) { + for (var j = this.elements[i].length; j < 4; j++) { + if (i == j) + this.elements[i].push(1); + else + this.elements[i].push(0); + } + } + + for (var i = this.elements.length; i < 4; i++) { + if (i == 0) + this.elements.push([1, 0, 0, 0]); + else if (i == 1) + this.elements.push([0, 1, 0, 0]); + else if (i == 2) + this.elements.push([0, 0, 1, 0]); + else if (i == 3) + this.elements.push([0, 0, 0, 1]); + } + + return this; +}; + + +Vector.prototype.flatten = function () +{ + return this.elements; +}; + + + +// +// gluPerspective +// +function makePerspective(fovy, aspect, znear, zfar) +{ + var ymax = znear * Math.tan(fovy * Math.PI / 360.0); + var ymin = -ymax; + var xmin = ymin * aspect; + var xmax = ymax * aspect; + + return makeFrustum(xmin, xmax, ymin, ymax, znear, zfar); +} + +// +// glFrustum +// +function makeFrustum(left, right, + bottom, top, + znear, zfar) +{ + var X = 2*znear/(right-left); + var Y = 2*znear/(top-bottom); + var A = (right+left)/(right-left); + var B = (top+bottom)/(top-bottom); + var C = -(zfar+znear)/(zfar-znear); + var D = -2*zfar*znear/(zfar-znear); + + return $M([[X, 0, A, 0], + [0, Y, B, 0], + [0, 0, C, D], + [0, 0, -1, 0]]); +} + +module.exports.makePerspective = makePerspective; + diff --git a/tools/ffmpegToWeb/Player/broadway/utils/inherit.js b/tools/ffmpegToWeb/Player/broadway/utils/inherit.js new file mode 100644 index 0000000..2ea40b2 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/utils/inherit.js @@ -0,0 +1,17 @@ +"use strict"; + +/** + * Creates a new prototype object derived from another objects prototype along with a list of additional properties. + * + * @param base object whose prototype to use as the created prototype object's prototype + * @param properties additional properties to add to the created prototype object + */ +function inherit(base, properties) { + var prot = Object.create(base.prototype); + for (var p in properties) { + prot[p] = properties[p]; + } + return prot; +} + +module.exports = inherit; \ No newline at end of file diff --git a/tools/ffmpegToWeb/Player/broadway/wsavc/index.js b/tools/ffmpegToWeb/Player/broadway/wsavc/index.js new file mode 100644 index 0000000..6e48bc7 --- /dev/null +++ b/tools/ffmpegToWeb/Player/broadway/wsavc/index.js @@ -0,0 +1,159 @@ +"use strict"; + +var Avc = require('../broadway/Decoder'); +var YUVWebGLCanvas = require('../canvas/YUVWebGLCanvas'); +var YUVCanvas = require('../canvas/YUVCanvas'); +var Size = require('../utils/Size'); +var Class = require('uclass'); +var Events = require('uclass/events'); +var debug = require('debug'); +var log = debug("wsavc"); + +var WSAvcPlayer = new Class({ + Implements : [Events], + + + initialize : function(canvas, canvastype) { + + this.canvas = canvas; + this.canvastype = canvastype; + + // AVC codec initialization + this.avc = new Avc(); + if(false) this.avc.configure({ + filter: "original", + filterHorLuma: "optimized", + filterVerLumaEdge: "optimized", + getBoundaryStrengthsA: "optimized" + }); + + //WebSocket variable + this.ws; + this.pktnum = 0; + + }, + + + decode : function(data) { + var naltype = "invalid frame"; + + if (data.length > 4) { + if (data[4] == 0x65) { + naltype = "I frame"; + } + else if (data[4] == 0x41) { + naltype = "P frame"; + } + else if (data[4] == 0x67) { + naltype = "SPS"; + } + else if (data[4] == 0x68) { + naltype = "PPS"; + } + } + //log("Passed " + naltype + " to decoder"); + this.avc.decode(data); + }, + + connect : function(url) { + + // Websocket initialization + if (this.ws != undefined) { + this.ws.close(); + delete this.ws; + } + this.ws = new WebSocket(url); + this.ws.binaryType = "arraybuffer"; + + this.ws.onopen = () => { + log("Connected to " + url); + }; + + + var framesList = []; + + this.ws.onmessage = (evt) => { + if(typeof evt.data == "string") + return this.cmd(JSON.parse(evt.data)); + + this.pktnum++; + var frame = new Uint8Array(evt.data); + //log("[Pkt " + this.pktnum + " (" + evt.data.byteLength + " bytes)]"); + //this.decode(frame); + framesList.push(frame); + }; + + + var running = true; + + var shiftFrame = function() { + if(!running) + return; + + + if(framesList.length > 10) { + log("Dropping frames", framesList.length); + framesList = []; + } + + var frame = framesList.shift(); + + + if(frame) + this.decode(frame); + + requestAnimationFrame(shiftFrame); + }.bind(this); + + + shiftFrame(); + + + + this.ws.onclose = () => { + running = false; + log("WSAvcPlayer: Connection closed") + }; + + }, + + initCanvas : function(width, height) { + var canvasFactory = this.canvastype == "webgl" || this.canvastype == "YUVWebGLCanvas" + ? YUVWebGLCanvas + : YUVCanvas; + + var canvas = new canvasFactory(this.canvas, new Size(width, height)); + this.avc.onPictureDecoded = canvas.decode; + this.emit("canvasReady", width, height); + }, + + cmd : function(cmd){ + log("Incoming request", cmd); + + if(cmd.action == "init") { + this.initCanvas(cmd.width, cmd.height); + this.canvas.width = cmd.width; + this.canvas.height = cmd.height; + } + }, + + disconnect : function() { + this.ws.close(); + }, + + playStream : function() { + var message = "REQUESTSTREAM "; + this.ws.send(message); + log("Sent " + message); + }, + + + stopStream : function() { + this.ws.send("STOPSTREAM"); + log("Sent STOPSTREAM"); + }, +}); + + +module.exports = WSAvcPlayer; +module.exports.debug = debug; diff --git a/tools/ffmpegToWeb/eventemitter.js b/tools/ffmpegToWeb/eventemitter.js new file mode 100644 index 0000000..87dbf6a --- /dev/null +++ b/tools/ffmpegToWeb/eventemitter.js @@ -0,0 +1,69 @@ +/* Polyfill indexOf. */ +var indexOf; + +if (typeof Array.prototype.indexOf === 'function') { + indexOf = function (haystack, needle) { + return haystack.indexOf(needle); + }; +} else { + indexOf = function (haystack, needle) { + var i = 0, length = haystack.length, idx = -1, found = false; + + while (i < length && !found) { + if (haystack[i] === needle) { + idx = i; + found = true; + } + + i++; + } + + return idx; + }; +}; + + +/* Polyfill EventEmitter. */ +var EventEmitter = function () { + this.events = {}; +}; + +EventEmitter.prototype.on = function (event, listener) { + if (typeof this.events[event] !== 'object') { + this.events[event] = []; + } + + this.events[event].push(listener); +}; + +EventEmitter.prototype.removeListener = function (event, listener) { + var idx; + + if (typeof this.events[event] === 'object') { + idx = indexOf(this.events[event], listener); + + if (idx > -1) { + this.events[event].splice(idx, 1); + } + } +}; + +EventEmitter.prototype.emit = function (event) { + var i, listeners, length, args = [].slice.call(arguments, 1); + + if (typeof this.events[event] === 'object') { + listeners = this.events[event].slice(); + length = listeners.length; + + for (i = 0; i < length; i++) { + listeners[i].apply(this, args); + } + } +}; + +EventEmitter.prototype.once = function (event, listener) { + this.on(event, function g () { + this.removeListener(event, g); + listener.apply(this, arguments); + }); +}; \ No newline at end of file diff --git a/tools/ffmpegToWeb/ffmpegToWeb.js b/tools/ffmpegToWeb/ffmpegToWeb.js new file mode 100644 index 0000000..83e9ba4 --- /dev/null +++ b/tools/ffmpegToWeb/ffmpegToWeb.js @@ -0,0 +1,117 @@ +// Shinobi (http://shinobi.video) - FFMPEG H.264 over HTTP Test +// How to Use raw H.264 (Simulated RTSP) +// 1. Start with `node ffmpegToWeb.js` +// 2. Get the IP address of the computer where you did step 1. Example : 127.0.0.1 +// 3. Open VLC and "Open Network Stream". +// 4. Input the following without quotes : `http://127.0.0.1:8001/h264` and start. + +var child = require('child_process'); +var io = require('socket.io'); +var Splitter = require('stream-split') +var events = require('events'); +var express = require('express') +var app = express(); +var server = require('http').Server(app); +var io = require('socket.io')(server); +var spawn = child.spawn; +var exec = child.exec; +var Emitters = {} +var config = { + port:8001, + url:'rtsp://131.95.3.162/axis-media/media.3gp' +} +var initEmitter = function(feed){ + if(!Emitters[feed]){ + Emitters[feed] = new events.EventEmitter().setMaxListeners(0) + } + return Emitters[feed] +} +var NALseparator = new Buffer([0,0,0,1]); +//web app +console.log('Starting Express Web Server on Port '+config.port) + +server.listen(config.port); + +app.use('/libs',express.static(__dirname + '/../../web/libs')); +app.use('/Player',express.static(__dirname + '/Player')); + +app.get('/', function (req, res) { + res.sendFile(__dirname + '/index.html'); +}) + +//ffmpeg pushed stream in here to make a pipe +app.all('/streamIn/:feed', function (req, res) { + req.Emitter = initEmitter(req.params.feed) + //req.params.feed = Feed Number (Pipe NWebGLumber) + res.connection.setTimeout(0); + + var Split = new Splitter(NALseparator) + var cn = io.to('STREAM_'+req.params.feed) + req.on('data', function(buffer){ + req.Emitter.emit('data',buffer) + }); + + req.pipe(Split).on('data',function(buffer){ + cn.emit('h264_'+req.params.feed,Buffer.concat([NALseparator,buffer])) + }) + + req.on('end',function(){ + delete(Split) + console.log('close'); + }); +}) + +//socket.io client commands +io.on('connection', function (cn) { + cn.on('f',function (data) { + switch(data.function){ + case'getStream': + console.log(data) + cn.join('STREAM_'+data.feed) + break; + } + }) +}); + +//simulate RTSP over HTTP +app.get(['/h264','/h264/:feed'], function (req, res) { + if(!req.params.feed){req.params.feed='1'} + req.Emitter = initEmitter(req.params.feed) + var contentWriter + var date = new Date(); + res.writeHead(200, { + 'Date': date.toUTCString(), + 'Connection': 'keep-alive', + 'Cache-Control': 'no-cache', + 'Pragma': 'no-cache', + 'Content-Type': 'video/mp4', + 'Server': 'Shinobi H.264 Test Stream', + }); + req.Emitter.on('data',contentWriter=function(buffer){ + res.write(buffer) + }) + res.on('close', function () { + req.Emitter.removeListener('data',contentWriter) + }) +}); + +//ffmpeg +console.log('Starting FFMPEG') +var ffmpegString = '-i '+config.url+'' +ffmpegString += ' -f mpegts -c:v mpeg1video -an http://localhost:'+config.port+'/streamIn/1' +ffmpegString += ' -pix_fmt yuv420p -b:v 600k -f rawvideo -c:v libx264 -vprofile baseline -tune zerolatency http://localhost:'+config.port+'/streamIn/2' +//ffmpegString += ' -f mpegts -c:v mpeg1video -an http://localhost:'+config.port+'/streamIn/2' +if(ffmpegString.indexOf('rtsp://')>-1){ + ffmpegString='-rtsp_transport tcp '+ffmpegString +} +console.log('Executing : ffmpeg '+ffmpegString) +var ffmpeg = spawn('ffmpeg',ffmpegString.split(' ')); +ffmpeg.on('close', function (buffer) { + console.log('ffmpeg died') +}) +//ffmpeg.stderr.on('data', function (buffer) { +// console.log(buffer.toString()) +//}); +//ffmpeg.stdout.on('data', function (buffer) { +// Emitter.emit('data',buffer) +//}); \ No newline at end of file diff --git a/tools/ffmpegToWeb/index.html b/tools/ffmpegToWeb/index.html new file mode 100644 index 0000000..0318990 --- /dev/null +++ b/tools/ffmpegToWeb/index.html @@ -0,0 +1,45 @@ + + + + + + + + + + \ No newline at end of file diff --git a/tools/ffmpegToWeb/package.json b/tools/ffmpegToWeb/package.json new file mode 100644 index 0000000..75640b8 --- /dev/null +++ b/tools/ffmpegToWeb/package.json @@ -0,0 +1,15 @@ +{ + "name": "ffmpegtoweb", + "version": "1.0.0", + "description": "Shinobi Testing Tool for H.264 over HTTP and Socket.IO", + "main": "ffmpegToWeb.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "dependencies": { + "express": "^4.14.0", + "socket.io": "^1.7.1" + }, + "author": "Moe Alam", + "license": "MIT" +} diff --git a/tools/getGitLog.js b/tools/getGitLog.js new file mode 100644 index 0000000..8bf9b4b --- /dev/null +++ b/tools/getGitLog.js @@ -0,0 +1,2 @@ +var fs = require('fs'); +fs.readFileSync(__dirname+'/.git/logs/') \ No newline at end of file diff --git a/tools/getVersionFromGit.js b/tools/getVersionFromGit.js new file mode 100644 index 0000000..b2009f5 --- /dev/null +++ b/tools/getVersionFromGit.js @@ -0,0 +1,23 @@ +var fs = require('fs'); +var branch = fs.readFileSync(__dirname+'/../.git/HEAD','utf8').replace('ref: refs/heads/',''); +var version = fs.readFileSync(__dirname+'/../.git/FETCH_HEAD','utf8').split('\t')[0]; +var rawLogRows = fs.readFileSync(__dirname+'/../.git/logs/HEAD','utf8').split('\t'); +var prettyLog = []; + +rawLogRows.forEach(function(logRow,n){ + var log = logRow.split('\n')[1].replace('\n','') + if(log){ + var log = log.split(' ') + prettyLog.push({ + version:log[1], + lastVersion:log[0], + time:log[4], + timezone:log[5] + }) + } +}) +module.exports = { + version:version, + branch:branch, + log:prettyLog, +} diff --git a/tools/httpHookTest.js b/tools/httpHookTest.js new file mode 100644 index 0000000..26147e7 --- /dev/null +++ b/tools/httpHookTest.js @@ -0,0 +1,23 @@ + var express = require("express"); + var app = express(); + + /* serves main page */ + app.get("/", function(req, res) { + console.log('Home Test Success') + res.end("Home Test Success"); + }); + + app.get("/test", function(req, res) { + console.log('Hook Test Success') + res.end("Hook Test Success"); + }); + + app.post("/post", function(req, res) { + console.log('Post Test Success') + res.end("Post Test Success"); + }); + + var port = process.env.PORT || 5000; + app.listen(port, function() { + console.log("Listening on " + port); + }); \ No newline at end of file diff --git a/tools/matchFeaturesTest/PeopleCounterMain.js b/tools/matchFeaturesTest/PeopleCounterMain.js new file mode 100644 index 0000000..553836d --- /dev/null +++ b/tools/matchFeaturesTest/PeopleCounterMain.js @@ -0,0 +1,109 @@ +; +var argparse = require('argparse'); +var datetime = require('datetime'); +var imutils = require('imutils'); +var math = require('math'); +var cv2 = require('opencv4nodejs'); +var np = require('numpy'); + +width = 800; + +textIn = 0; +textOut = 0; + +function testIntersectionIn(x, y) { + + res = -450 * x + 400 * y + 157500; + if((res >= -550) && (res < 550))) { + console.log (str(res)); + return true; + return false; + } +} + +function testIntersectionOut(x, y) { + res = -450 * x + 400 * y + 180000; + if (res >= -550) && (res <= 550))) { + console.log (str(res)); + return true; + } + return false; +} +camera = cv2.VideoCapture('test2.mp4'); + +firstFrame = null; + +// loop over the frames of the video +while (true) { + // grab the current frame and initialize the occupied/unoccupied + // text + (grabbed, frame) = camera.read(); + text = 'Unoccupied'; +} + // if the frame could not be grabbed, then we have reached the end + // of the video + if (!grabbed) { + break; + } + // resize the frame, convert it to grayscale, and blur it + frame = imutils.resize(frame, width=width); + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY); + gray = cv2.GaussianBlur(gray, (21, 21), 0); + + // if the first frame is None, initialize it + if (firstFrame === null) { + firstFrame = gray; + continue; + } + // compute the absolute difference between the current frame and + // first frame + frameDelta = cv2.absdiff(firstFrame, gray); + thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]; + // dilate the thresholded image to fill in holes, then find contours + // on thresholded image + thresh = cv2.dilate(thresh, null, iterations=2); + _, cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE); + // loop over the contours + for (c in cnts) { + // if the contour is too small, ignore it + if (cv2.contourArea(c) < 12000) { + continue; + // compute the bounding box for the contour, draw it on the frame, + // and update the text + (x, y, w, h) = cv2.boundingRect(c); + cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2); + } + cv2.line(frame, (width / 2, 0), (width, 450), (250, 0, 1), 2) #blue line; + cv2.line(frame, (width / 2 - 50, 0), (width - 50, 450), (0, 0, 255), 2)#red line; + } + + rectagleCenterPont = ((x + x + w) /2, (y + y + h) /2); + cv2.circle(frame, rectagleCenterPont, 1, (0, 0, 255), 5); + + if(testIntersectionIn((x + x + w) / 2, (y + y + h) / 2))) { + textIn += 1; + } + if(testIntersectionOut((x + x + w) / 2, (y + y + h) / 2))) { + textOut += 1; + } + // draw the text and timestamp on the frame + + // show the frame and record if the user presses a key + // cv2.imshow("Thresh", thresh) + // cv2.imshow("Frame Delta", frameDelta) + + if (cv2.waitKey(1) & 0xFF == ord('q')) { + break; + } + cv2.putText(frame, 'In: {}'.format(str(textIn)), (10, 50), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2); + cv2.putText(frame, 'Out: {}'.format(str(textOut)), (10, 70), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2); + cv2.putText(frame, datetime.datetime.now().strftime('%A %d %B %Y %I:%M:%S%p'), + (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1); + cv2.imshow('Security Feed', frame); + + +// cleanup the camera and close any open windows +camera.release(); +cv2.destroyAllWindows(); diff --git a/tools/matchFeaturesTest/findwaldo.jpg b/tools/matchFeaturesTest/findwaldo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..96b498abbbc8dc179a1d3c6015c263d9cdc6d60b GIT binary patch literal 570797 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%0DK{qhpI(88#i}y2 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%0AuM^#tVoY zpp?q;F=xu2Pdo$AVztIpbnKS577mv?ZtYuRl<Y%OojPcHOa1el9G;yaBc6Y(|C_TnrnSW#dp_FXR7IUs~(+fhB>t7x?R3( zrWYG=b2N-tby81y&VQu1pN15~ucJ|ulF9vw#!5+f);^lPf^JGyZBH*xL z*yhYXxo#~{RcSk4%%OFr>Q^#FZwkkIYa}YtnOb<OK*$$yIWJp7sTkT9 zk@e!eM(RqVQq?Y}s|1qsJ3TVf;s%+hXo=xV8HTDXZChDb3}_l8l0h6-9%mT&wt{+N z>0Z4X*zBzeX-A(&$Vmr@zB_48de-)nnTF@p<(}OxTkR1>iW_umg+57)1Rq{`tsJG; z!W8H>?;;Nk{6_J{hppf1o-Ey`%dOii5Z&EbNX*95FBrGBh(;ukEQcG4uXa4*pEZ}g zp^aE`N-=`FeGXkbFXAmp-%!x3CX&lkOPh@(OEe#AF^N%UGOCnBaU&8?bPa*PuIf3O zs=b%;Z}U9KQEG2XKB1{-K036$^7SdDvo4m&X17~S;Z-u;=r}cYjm(+<(S!|+8b}k2Sp(BUQ8>}sV6AezNe>w%l*8ZZj|kH zf6( z1>c0=P8Fjs5OZy|msaj2SYr5DOBY7=Cc`k|PE5>FlOw7t-T#dDbOiW;} zCu5mYY^~w{00h3CBGTr+iI(?LjtQ=zZP3K!+TD|J`AaNr8INq&B&+*si7hT^LaL=c zclI^=nUSdYvggD4rOm#Ft6j-!Z#x_)Xo5=&%*rNF`?(jZ4!H*$S6rwztj+NmgQ-?k zddc7KJ%hqA>Qi1?c=-0}YABw{xm!{v^**!P!u9XZ{Irtx*5HO0bxu3%c~E1R@f;z{J`By3R?9DvF|UWUHYhd7QHuiVWjRq5HD zZaWU+9nPZj!Fo*gk87C(GDgt6a<|%HXrDWxFkE@D?Ih>r0O!4Zg`KR=C1Rv`M~E%p z@U8Xzx*Ke~mcYD+2$}unFrRpDCpFJjEzg=wDr@lbIp(>et1Rl)y0dCa zJ5HL1iS-##^*u7zXo55m1V&eEc_KZEK6b<8?ONu9sq)+5qaTI!Z1nP+bHY0%%%0_M z5^0_xu(OI;AyvJV{JRM>`JL_~yV!iN5s?|Q$R%UuAOue4hoPf*kEFH*|yZkr9Axsb;r#cvK&rcO#37@_wVG^n>KDXy}U{7(fq zuZf*5qo!U-HMDR^_B(cQ3fLJHBikGAXH-my1H>2@+t~4gU6g8BdG{_+y{u(wejn5{ z3#qjY2(7$Vl7^lSDP*>1XUS=x1}02yIFcsG$IcEjUXC9ZeIDrZ@t7D-ba@@`#19$1 zt@iyxUVR;ppKSK=BBi7)9JmU|%PSmVvgJz}^wg7AJm}#mMRM|*G5l_V@59$RPm3*M zH<#8k4La#pDI+j2pq?feiQ7B(FCBVRP1!PNV1IoV7ijY%ozkHn+4|0)aUP3dWbql< ze{((LsPMxIKin>>Gry+nXRUd7dC4c;v+j746$;fM8g_A~9-ZFhO>e;OW%gLDrnYEh zQf%eaiLkjoX+ky~j|8}0LqQ{Fc10>#oLX(`C8Oo{zu>Q#^YLjWr5|_5hfMISb6d1b zR(n6R$EVM4WZqjP)S>>$$>s>&X#*qfX4;tfcV{JBu?agZ+P~U+G6BnMStl|^hzk-A9YU21)Kja^*y@#ObMwpdxyo30n%YfA zP`uKPp{-4;TgRyCkw)uomS#tIuT@y|F~=lou0CGPm9I)GL(6qvGiSYcSH&>MCbPa_ zXR1B?ku^MP2N8?}+?ort9}MtE%YZPSbAg z1Hr59UEvW7AwJMziZF|k#e+X19XYRa8JE?gMY?i~>Lse|a8t!8%T;CE)bRd;;k#{i z@5QFZ+C4i%5+oDCgv~YX#Yr~yZzwO8fk)qL4wdC$=UG#Vo4lFbPMlx8(G>NshtWTW zH7m_uQD)cYmQ8X^Jv_Wc31Pl78DBDAE*B}6J3-+<&3Y<+@?8O`LNc6RzO}K=S;?$v zzY%l|8&|rT;_k}mLu(|m0}-^40)imGFj6y(#Qy+ys@HrV;VU!8#$zFgz|@={xj1ds zGmNhOU5&dvX3s*t*YrI;NNx0)H91A-3zyk*1R_Nl%VH2^3$y#U?Ogb}YE#o>X_De+ z^;o(5Qd*qUdY|@ZhT^%nhV}IMe7GgJw+R%UOFx})v7}AA%SOR4+>RR@3gLeBPE~CV zmloECtoRq=WyQ6gkl)&H>OK_m7TfJo#W=l=o;t6e*x$^UYV)tx~z8gn!4|?VzM*3?G8zeRh>W#Gm*jKy56X}o?EJ0_wnf-HdmZQk7XFWj68cbU*g);=Otr;jXt*K6^N+I4vEt{Yfn?bo-4rSg_MH zYi%XxpZf|q;YC)GX{R>MP=FbgRn@sYaywT%=Gu2W=u?!j6qB9r?^xThJ_*-!jUPkS z{$4O&!!q#TBD-pEfp3pOYM=RtCH()w7MHmCtGCc$XJV%SRWh^gQ#z{{Rxa zHK1#jH~#=+ywswCA1-#A%2tM5rCM8En-zltj7qr!p|4jNm-|{yFnq0_Etuvwj9o8f zIle`0JrAS&IpUoc#5!zRhL=B?42qYnBGTE-7aeB>Tdm5{Q6p_i~#&WD;5j1X+1!e8Q$>Z;(7k$sDgG-fI>%Jdc z==z?Od829(T1Z9A@(nm!mA3&|RoW$VRAJ_P_)P5H0k4+L>D8xO+N;G{*FJwA%?gf7 zLz(g4h&25hT+{R&Rt48BGAv^#=ZTgW>lds<^bWC|< zIk6DC>Tx~}(!L(g@h4I`5o?6Bf*YGy!?W5&ICfc@+!Nb!V~lm%Ufy>(MvQHx-Jjfj z2N2i9!kU7Vy_C02{)hk4?{xiM!$r|;t=cGcPZ36v-HRJvCL4hRyA^Vzsp32#ZlsF& zn(9?*$vq)+Ca!ob#qY+?80ymNR<{>cNjq(}g)YsEAwv{YhBuNjeq|##{* zRY!c+Jl#l1$5k6|cikK~T5H?d#;1m@qO$PioK{!YYkR4zw{}_`rr6N$llMb%E@6w1 zScYB+tm@6mZCl-1a}zpz^Y?q4Zh@`K7sSWb?d*QsmY0{eQ$=dPC=C-p?-R*@NVu0` ze|^61TKb9}?iw&7ktyhM{v^<~?+?zpX04?Lm=<`DTqLf;C4nLzFeHQcfnm=|^Jjy8 z)0s)5>}YW%B|=kAw`?c3g3l!9)(8i@nTSA77;C~hPg4QT3Z9lX0yPuG`dt|(tGH`r|Wsw*Ta0%M@+-Iwi=~TZWXz}Zd%gcC%p4NBTY`TF*ni))yq|qY>GD(yB$D8t5s%NsTxq>_7A zgP!I|<0g{pYn{1v9V#(iMmczy2hs=4?@Ft9<}b_rF@#E zyG-G)1srrg!gh8VmxrU#b&VeX01~{nnv7Q#o?O=rAoE>88&I<;00nPR?Ot^Ty_w%q zFPP+X9~$X;Z^E5FNWM#%H7ko7nQa77mjV@WVbKz|CuJ;TmCs}$U)HO_g?q#ls?W1*?>JHXen zcz;y!JI@+wsb`z(AdB`{6fV+%xN=iJBe!lFjz^n;#KqK9?V{P5QL59oMp)3!q2Sx3 zxzw-q3(pRSCKDktT*qk|tUqT~4AM!3{oyjF2c|aSxbtkf7`j%a7{<3U*4Dps+*DjO z=yKl_{7!VQ2|;gm>YBfZ=4+GDznM~+ zgmu#U`gsh{J|gHEKf_5a)tFw9bM|y-*vE^9Vv;nt^6;U?Mt5Xm718xcI;uxp>c-NN z_*=Rb!%1CZ;pUs+i z#8TzDPVZOu=yqYLxNdhJ3hutc;W2d3G}oHN+?TVJ;Ot}N#0batQ;PO*^c-oU$;Zz1 zHqhSCG;5uE#%i~5v{sf1x`e3w7nI1!ZVrEi3Nw3CN>Z4Xab^{5PSx?Ih9C;B`xB!HkQu^9`6-_A3GT#D@Uw$RM@pW=&4yWKy+`cy^c z5!}ggu?0w=ic4mNSd)c2W12=(AH}qHt4JG3Gcs*X?^@PTZEP+LvnodxRbl`~@+X*i zDxe-;Y4jD+tdZwVs(M`VO@C8+ol5R_p-6@7lm6{p$yA<1wvAPS;fRh6-!?KUz^;`_ zt=~;Q1J$Oj6nc+>bnP*8n>W7KE^V7qX|)S&CMnh;W0{#Ezyr);(E*NrmEhv5)%LD2 zrll2S%>MurmUTVjkMZ@(P2!Cb3o9FeZ)4_PEEC(ZT*fDLmPA3xkp{^fLi6{%E7PYr zPY%`7>2szGg_>CItuz*+B)FK z@9%WcH;PTkjc(yOR4^i_d5yGgWtfEvA!Go2{{SiAb6uHyCG4T|DorHI9u3oOB-HLT zE1eeWS<&yy+sJ&kxe(83x65^kPN^hv1sG41f-naI(Q}GcPRyDzySvopF7A9!Z-3&A z2gCMix(2^I!EL5P8^N^VW>}MR$FpG!3gZJcPMjR0HvQGLDT(xC!m&&qynqnhxsDJIgj$&T0P&RfL) z01Lb;;$3bnPR8P04^@L}N%kvvWwa*Qi@U5VwaY)4q%*Dv9qXc&I;Ayd?;{D})S0`b zd@At9o#E+hd`YJd5o#9~W_#b!2rVM=m!G#-ffor#idlG@S_BLZzRCJ_%}? zU7h8_N2J|-o*3_K9_ZN1pD95T!p=TtAI1mG*ERH#rx|L|g&cKyS5TWvwadR0V)%ck zXfSC)NN#loiW@yTI}F@U9juc^vIxXJVy+@nu(;|zUTIG1F2^$8Q-HPjYob^PHBE0= zvcAwkV(%QwYXhu!P$h4j*^hYR$4nlz;JUJI$v$)G@fq!DQ&i(T?aIjL zWWf2hjApXUB$Y@vxyOZ8jFQxEh`cK|hXsxG`^~GZ^kUvPBEGmSBygwhRiXjhN0-`s zse*=XqawTTn3%Y}Rbv{I+j^Mya;%;|hej6~XZ8)%ybg+Fdc+NsS%D?2buf zWPGl2Fum*Az;OLsO+Vh$bothn-0`uQv?(^D9&TOColfCyWs=@e5((Qh?< zHuawJJB5+7nJzaa{1K#kBAn-FSH#LbLb+p}l~pTp%|_ZB^r>?zrXLkNK{k!>w?MPA zkH|Wx7c+TfSIbhqYbe{>%(w%N!j=M!>dt*4>}!jwYEh3?aM!*S@ivJBLiX)%w9Oh@ zYsa=lV*?q$Xvo|~QbK_X6$QA)K?c29>YsLxE-A&O(Dv)wX1$u{PqvmwZC6mYve7Oj zIk~i*lg+#_PFS~-92>TVB=u5z4-$-(lIvsD`wr)x+uztv9B!8P8hzZS$y7*VdrQA4 zw0~%}LnKa{)dTHPMo$B|Dqtku+{@O-UJF01hle71A!FAxcGJ^PpIL&|!QG)3hSKeq z%}_HEf~t(;cR>7L)>6Yb&dN9WqrRsW)Rb(ZlkQ9Kuf_UaspCtjqqLk^*+R<%?5#EA zqUHRyGx=v^ajFmXaj)L#lS>_jlqn>)Z_ytwj>gol@w=X_qIe?PR?zP5^!u4DbflPE zXmC7^(M>(8E-tQ_vh5QzAV!(m6XwArW4{T6vgVri{{SN@F}CRQJxjsS{{X^4rNFSH zI%W0Ti=_For18SiDUL{1Xqc>v8$R{H3>0&YwX`TDK5Lz|CeupRXM6CMT8B#3Z!Nq@ zsoRNWv$umx)GlO5n(b`vZeg2t@}ta2Fb}BOd)D;eqkDBTuToNWmgw$$Cw7;Xek6(+ zQ|&S97x4)<0tt|bA#arD9$brz9)hgFE4@#hyjS7W@XK0g@_3HlTAmqhFE1?Z)RS+R z(?crL?0SXYxmP;nq(KN8#bAt49RdOtK}+X!6JB z+}tJ2$C|uS6`6d&kTZ<)UcFz1lTF>Eax0_wXlvdc(excc=K3kFmh)3@F(VN* z%wjVHW;I=nuw{toF^pB#rs`qkE|CgzQK+NUo1P``&xfSZ&awh{c@i^kJ)~H;X=P{y z&6#;VeXqT?lK%jCam{$NteUpn4`vkgQrlCH)Ad`c3;Q`>a|HTO{{V@6!HHx@w#bXe z`%KI3IIfs$HrHe5r?zWr@qA@i47ocJPmgE<6;8Yp7|Llj-2<*BV?BnXceh zFq@ej;zf%n>A9oZyCnR^x~bt6I`OIew)_lb1yM9AYN$oY^e!ijP3Kx#eXhypopkXEuAy-y&ATz2IaG#4F)VQfOePes z%(xZhQk_bYyL_$ej+IGT?CP{{_)4`~i))qC*6YMFMX9j6S#cDR*cj|BgB_nX!z_=M zOcy1J^IkS}i>9R|UN@qpPCtFzpX4fP`x0IFgT#$tr%1Y#>oZL>v!RkSc8BFCh2x1) zimJ9gKr_h|G%}nY)@rF!UeEV&kNv!gl%(Uiv8B9H=(^p%i8VOHnv7QWziXJR3lvk^ zB1Xswz!6Im9zTk{cND8%q^-S8y#i<=ulj40k^TH788ja7`<7oV= z$yk`#W>e)p&_?ad!zcjHBZ~cEGj1u%M$z)_i&booneQ~{?d6wwN#eYcb+&7Q9_55= zrGC)g^VejnyB!!GO7pP|r*+W!Of&a+TGZ{l0jX*b#rD|}8{1tLS*_)c53@mdMci<* zN&Ci!?H*pk8xrOD9jixA+Q3k)?5bUo-X;E@;rN$UNUrp#+UnwHVnWSsE-nEJ*= zF{{ZLnkGUu2T?XY`bW|Y!`cK^k3q8gAW*Fs0j5$@8B(F!Cmb62 z+VFK;6t?!S?y;;MhONAhq_lcAk!ZJi!k>Y(jPu3&QwHiZ{2Jegbs06wkXA?(MYi2AL0L>lT(Y4c<(p{q%_(LTD!WBkm4;C&UTXS| zsc~}Jg}t2GEv>xb((e7^OB;LanA6XJcMmz;IE?+kc+bph%*<*xYH^gJ`IXduCc5j` z=!_DxZ{%azUf%1zDY3V?)ofi9&kFQ&OqCXJDrQ!%=yt?xvjJ%PE z%SuBw@`GqZlc#>%sxy4^X{uUsUwd2f>|IN@$dlJ%hr|yH-Dv(Fnk^lE(QOn7I%(*K z%~&m+T2`6&0IZOR^}4J&Sr*N zb38?vSYs{FQjP!OO=Wv@(nV(!MYSlSo!(O? z+GKYN<)58hkU1a4o@)%h5r~|vUY9FN;=R|Uh{s~y9}Ou**)HQP^t}Y$OC;CrrLLo< z+0Ay*#2rgq+n6pCOCrg!q-YBgPdmLvYv`AHhqgETX*(6>V zlUtrmI%t~HO}(~?=F3qLMkk%4DGue{3;6-Y{@!O^mE%0dRB7{Hntaadwe|duUmY59 zt!jEjMK8GV<$I-(ZPwwM$VqULTdSWXW>j@7s7?T3$giPkHMXWSp{kPG-cQ!d^v{JF zY`0z+N&Klk-=)tW7UkL>I@)Df7Ba(?JN{^yh68(MyiC@tsA3dlq-sa*YpKUhpR|UZ z4u|4rhCBgzrD;AQx6`lhQQ9~YOVV3o`7+5QvKCE}d2hHdW^Vj-6_#0#tgA|uT_YZ^ z^0~!3xF1UUe6tk_n0eXW z(qEH2Z1vuoeqX9P9SlTt?Hw?7PpmxcBH$k`-tJqsbD#DhKJ}E{qH^Vw-0^p}!xi}> zhVW;N)O4?&#bK4IN-yF^-Y8T} zb49N^9aqO&mA>%9_wd3X7wCXyNc2+tiINx1# zJj&a`J`L6Fk*2k1H4P3SE&MAQ#wA-&8KSs!Ef?>{%7h%@Nj+=OmMXL)oLX_7-#_v^ z-bBws@CJ=x%T};X*%Ass!J+1pB&n4l1U1|FqTGDn7nYbs?rIz#-=ld+mJc0A~;HP zD)LiX?set(RZ1>LD|@E+lf$}K_QVqlZAVaPt|HSO8+oLPIIyuwqEPG|qQR4I3fL9u zT{+ow8%;+2%03s1>|PyxV#Z)K4G6=jTxrmopoS7mcdF}fprOzPK?(c?GTfO7>SaQZgu>N9Eu!qlEbg&d}I7 zsLOFG6x3rK7LU~)bsWB)B9-FYCl1;i--3KgJ&%f!v@08EEv0BIFKlfjmDcagxRFwH z^Vqs<3QFVdgU?v9tyuDRX)t}Xw>#|O+A^DFNk~+o)*$IT@DL-2{g-@A=PwP5o5WHSy~&W zSWs`2MI>AIfO3jXc(1q2Fpm+3w0E`9@8aPq(S6VV)AV~CAH(`u$KvO-nq5r5u`@;H z%zH)(Kr*|EfTe)xUnPpGI+bNlqLGI=5$0!=0l6&(jBkgydUAFVv zNWd0S>#-Sn8se=Ak;PJR_X_@Hi46ZThh4dd#h8bjVDrkt9E&?@s_QxTAPm$Ucsr#?CAtI z@_DNaMCWJ|NPuqYTkm6zmFHJ&$u-ULE0HGCEcg#phSyMiQtDxIVWGuyH`x#)w31F* z+S)%c!*6D3bDhnA0VbwvuU0rEa=xLic$)7_y|HVhxZYuV=2b+ULvAFjv8qUx>J$lj zu0I;hRcc9Xf9vl$y^?9S(Ct1P_`Aab*F@2-ac{0#O>g!Kca01(t6!@usV)qK#9RfC zf&e(qYf5ma=XCVB&o>@ccJOF(8|fp{?4RrwHy0M`d3i6}E~| z2SMFpadhd)ueKEF%1L%O4~|08#`8?IiJIo@LvyHK-b~(Q%%!mmTjU^djr&vpzSZw= zeC0XRuRW>7{zsjh#ypXN`%*`$cwbGnxA4B7q+Uh#YuigGV3fizNm!Lw#UkgOy_$j?s#p+ zrVhLw+_(9j4s5w=(`$2z@k`ydxvWKRd36HCeQ?pnv&gERbfwSA7!2X@Uba=0(#2rn z;?!y@-Q33&h@C3UZxgEcYhgCLMXlbMXMYEW;St*<#Ph?Hxt2*vltq)?0NhV4 zmFeJSIdy5%=BDh{t#>h-yDR)2xzhBX5^7eu(Mx$P{{VGvXC+EpLvi+Upn9;7b@Z=q zimA%39}iX<^HWRiJo-90NBhU1{7JvoX7HA!b*4#cbD+Jtt;Fdg84PAnw*?t@Ap$U0 z@jjgVh6)jlM5pf5N2Qm-4!k+`x#YS|sXmc({{Uo9wrTQ#4yC2ZD;VaCFUSKqlVip) zx3=GxrFZ*jOG)YGewU2MXVaRMUJlABQ~H-7TzdEUl-txC)Ve_3c?_fG?6H zxNo#F{l{!=JFsiG@~rJ^osWfQxU%rAhlnrcm2cM8!S3WkPsZyF-^Bqv8pqb@TT!zz8rB(AJgqg}=5oEb#jAOU@s0jRO+?=Yv zU%?!=-1lz}=vVq~nPj?NuMD14DIA_;QOglw7z1yW<+#D*eAVSXBg95llJ_on6{XDe zELdx|dT)ufwUf)ZxSrQe2w+A6JUzhL<%=GNHS{@lGwU$swY57i{_JdWJ^&ZP!g}wD zZk(H$t|v>Ue6vY4vovvr{w8@PZl2*r02S!9V|goBgTb0_+ai5R>h>Xbe0E5ZNTN^! zjm49$=a;uYyHs?jRimovabjlPhgYj!ri0{e|Z6BWVBU}rGNsMKr zxZzeeWp#a}I}VlUV(^scr#f*_=f5-gGpda5pv`(4iz(po0$Rs$XQ*6Fr`$yDBT3?d zI2qNOgZJWnj5*x3&6d|(&Xx6yV&Bf^t%RfPB+^%vw7!Vax6r&Rtl!z|@_3$k^q`^b z^n1C9c)%q21&f#1AFvrcGDUjM{fJVA*RfYx)MD_h>gzfj>3eM*!mX~4Z!O2pCIw3v zxbqJF``B~B@kFU}D@$XRrA1CxTAbI2ekXW>?@*q72g7pc8imj@-|7MvUPHC@Go~3Sgc&i=HgVyN$8`U)nrCXhH{VwBsnfA1^8Kv0>mP3+% z)-O|lD~7wiAzA2l(@r#Aokr=}wcNfox6p2;wv$cNG%qqc*a3@et;M;JEU~l7p`du2 zee82xSegnenQlc4M5Oru#Xvg0TDFHTd#>6~sNPSfv1`#JV(M#5MQj zZq^l@CJGumd6Ah}6CkMa)T#a-Q-Z*$yGuhDV<9*x!Sg0>KC||BoZoJS=FxWDT1ETS zL4y8xJ5|bU2d+Mut{T`HkdszBV^S?#Saj=&E@hb9{j$RSL~k0ZMnq1h=Q1u#m<@#k zABn6TRJvKBk|WdnL8R%P7)!l+6}Vj{S+w0pQx@V=1XiVlQce^z>}a+U%D5Y{a4YL@ z^X8_Xk>%8lq)_q2u9FRpo2qzyA+wI^87_S5IOBz-f*&gVWIz-HBKaGaaPCEEJK5MN zq~50!@gu-mp0%k*sK=<OZXFlu*}(FqzztiMm?Ms&Ih4_ zYH{iEcSd-cGK0Rhea=tfrM`ut{6W-h?5!XEC9Q7OmoCjIQn5454(8A9^D>p)lk(#~ zHFi!3ryk}Imn@U)U_u_$*(A)dh>VgWI|T_8kfg}J@CBF;!oHIt%#`R;=92eiC3o3q zeExBRaIH}#@hHE%))HM@Dm|jjbL7byU8E?(Z<~#wowlx9qNh9a)1_;iW_WifIL_`5 zp^jUZRb1DO=*rV1)AbEJ*`@8{Y!gT5tQ>CI`WUTIn?OAL0teXJ0hyQftN3Q0cP?mHA@Fg57?Mrmq% z#a=1H--m&^YEL^nTe*d=S2R_RO^b4X;8Qz6X6E94E_4{sGv zj3n-TbSt^RS=}{qmaD007xFc^(pGpBh+M}K+{AXq%_^IfJ7Z|!QMUu-LfEO)Z{kTLVeHy> zD10K-wfzfG)URwTCAot7#q3$YWdcc^RuYYjGYK()T^Pv1ql_EXO6A6zl0KLoHt=?< z;r$cCejV3QFRta&tsu96v{z{aFB?q4HeJhzqixw3#dgM8X}N7_xxL}f4otd!qid>J zv}-lPJ-3@8Ty0XOF(MtzRoQ-KJaWeX3WXPDnb(M`2Pn!8{J)vN_%bWoe~YvDTKX$_ zw5tep7q`q|o<_SCmlCV*+@&(v3OnS}jJ3Csjaj+L$@MzBZ4coq_`6ZiAkgerTfm;` z1%P0oK*Cj3${-m4wil8Idb1v~kSO&cAM>7GNISnZZrVLK5}DwUSv z>vIEKIEczqR_JzM>dF_hwbhO59amYtlfxHxmMdj%CA5oeFqK%!k7|-_+M|P*gL`8Y zhDS~m@iR&4_dKYT@ADSjz0Io7QIeli zy3wTZhlmqK(ZAsUk_`t^x>=@@c_df~xQ+a`lgm|+VU0m$4U@uxdSybNF6F#SaOLy4 z(p>x>&~$I?uM=A96JKe%b>wmDUu=ysqTW*z$c(EQ+Ow+eRv&jJsYN5EwqaVU=A5rC zUSE-S$DTZI5BO8V`WkVn-DpqdM$Hs{QJw^bIV5QY<>bgmmf6U`1XoTLlc_r^e9tbl z)KTMh*Rj~lB?4Oqg+}|x4#6C5e6hZ0Psog0Z_UB4v&7fJ`?Tvvk=uPgL+7bRzO$z; zZFWA4_*T}-;J*W-O=?|Yyi0YR3tcys&Kt;bM%D}dwD%S9Rbv%4qwwED=;6&}&ADIV zRpya*tm>9CT{_=cX)#Nu$88LkPxhg3^MsKiR>tEDYqjz6v8<;@oitpkMlV*5B28mc z@b`h`iLI}79Yw9SK^4WD#To^NY9ul2xL4Z4C1l!Lsl{+CB-HtuvC|CJk1LF1q{_bm zWz{Y&8tU`xpvR-gBaRDr?d6Ak(_tnmGbj3=mp^n2SITjfbt-h>Z~1z@dVj$*!t1Y* zr6`6QOI2`w(G*0fJdzAEO2_{BWe4eAys5QTqyGS>l%M1TzAc*e!%y(8r)78cS?;1u zI(xq&+INOHmD(wyY2$w_gpL%j>}$)(v6U&}F;t+gqd7@^&DlaS(JNOvMuT9`;Q;w>~iS^i4lW~$~ zqv|?VovFd(U%<1*4;jd1Ju<8?%5mx2+PTdmQNi5tFBf<@^k^ozvD4PlIc-`!N)q6# zF}28Ll{}*^RZ;em;WLbrn)9)^H8iFCj{dqHoeHJt zn0a8b42%{B@D;^EyrV`{6Zg4_lD>x>saWY(I_g>3z}C07m!s@c&XXHRfSeVM-Z;}~ zkaijo{fE{$m?|yTe~{jNeb?g zK)~?BA=qJ0YVd32)w$y=Je!20cduT@pD0W0vVA`K*Flc%`in%$y_pm6QU z-;*M?6sQD`TpH@H2Tlp^bJwRneNhgnduG~_!5ySmGg!1?AY?BylFC_OML1C!;rBS( zo|x-hG-$3zE0a=IdK?#xw7YF9P>x&6T{_QC*Y4oebyw60Kpw~ho+y+t-t!~xMEm@= zUfh-FH}A)t$wkF-{{VZd`-KVe%Uup%LDwxWbq#v^$c8O?+DY{*PZM0LTiV;lFO;xm z)S=qVhEyzshUW*ZV~?d$pRtz|C$_hrs+QBcSl*hMQyJ$zqaQ zS+y&zHrn-WZ9!FWFdlORASm4@%n0fqwRPqAmr{djGLI~rb?lAkKi*y6$m9Hfqw1QE zimxqhH0$fjtL--O+e#4JEv=MZPw%1u&IGxNCV3-r31iUU8uutTsH+}!G0D#C=7zDS zz>9qh`d@`rMwP1BN2V#fy)PMSX?&>;L{G4^vLha#b*_Vr41#+*S*<2{FJRNIC%w|< z@fGZHTuUT2)5mpew)U#YBwGMY<$7*7q}`U+1g>=+6W8$;R)BC^yXcp=v{ z2xoYsWQh5S@kj&YDFBYZ@J8&`SeUm%l9#&EyN~KsD|<`L^xSop&kT6h$X?pZrRbZ4 zwtr{{-)gd+Q;88|0*TIuAxY!&<(9r$Uy} z>Jr&m*k4A@>VkWVn}>|60g|x>E7OsR^K(j6k4b zInRh5Fw(DeH+>dQw8zFm6{;vJhcp1NW^{YmKk+ItCs7_*aLm6-GCv(sw*uy1Sh==IyS> zOQFuT`klN|JHvB-CBK<8cnlO0tqb*BNxOwT*CVB2#xzu^!ggNM*=oG|m}K=id6aJ8 zrE8t^8Z=s+hN+}!sdEmitzNyHGulj$N|3Bcepk(xzR-7BNiib6y zeZM2ns}$_Bn zmc}$`$}8&h{>e7S!8Q+vqgQ+fctYF&pHas<}MWAVV2Z(J@N2nX9q7QC|b<8&sm5@rO=6^B) zzpo9njAIq1614ueD6L~-$)7auC%M(fX>AUjr|O!7-*18#Me5ndypKLa^I7($e90x2 zULF2b9Al}j{*siHjptG@hODJ$rmg<~h%aunh!pA<5vXKWZ`~w##6jaJ{1X1~50#s- z;=Xq|%qI#|>QR@(+V!#XxrQcADaG36WuB*}=(?qxl3SOvxSI0P;y6=qjtOE+DUE-C zNwsi43h$!oR7?K7LSH+cjtZ@+Cnu*VQ&ZCV^B9^{y7XB&6`V9T4S zgT^*mOwlgoi6nE!&$*lBG0>w{4xD9qdh7Ex#O3uWMao|8pVo&-<9$0^x`rpytbeqj z5X~I+0`2UWJ8dz|9Ei#tl&KqE<-zr@oXV=<=*jzC-p`}R8Q0`Q1MaJcgT;Mst>t8Egs;gPkvP%1y=y|H@m-kEJ4PP0% zx&rfY0sOY|3r8BL82!?1#yGET6x1T4(D&9@`dDq&pd(DyR+;k1trSPlI(cWOHDsZ@pZk-R?PEi7Kw1J5yY~W znoM!?7duDyK|ZyLsTIv7@iVgtOPbL8F*kJ&56KRQZ{VIAkpe{5wwO?2S(OM2xwk&g zH5Kr<`f;8$QKx64JryoxYiN!Z;^x-VSBlc=ZzkFus~ed21&RK44Yf-*BX2`pQj?uM zHD?=9qfyztOPc<*1kG&}PPf+cw*LU#TWyf4aso7{fw}9BwVf&wOIxEVwUnNRvyX+E zhlle`0CsIZdtttFdG+Y>4QG+|+qW?laPE=emE+#cqgT6T+u_uGr_J$rKh0GaEWhlnmd7I-Sc?*3ox%`)l`+I7NVZhqM^8H6`2xT~Xl#7ex3V2*~p zELK#i&z}CLmroMm7LNkB@z037S>o#{PMrk4WR}od=@!aTKQ1}E!5Ct9eC*A+o7TN- zES?&S>B0N6+~KOdtdo1A>lmz3&P&JJJkiYN;hE%CMR{aqa|*5qG4%uto-j>(wYjBd zq3kQz@?Va2jX2V8#Hl^J_IGeVz%t6p1agAvc>Xd506x6e+;FY0R+?ME{zrwJ!{C#9 zNfG>D8V;wW=yveOZ2IQ6J)~AQW(G@`pdkZ!&zwpKkynq;itz9>=S?+tZ&SXqi}g6& z8^e#L_`=6Uz1EV#SXxPRy+u`51tlU_cIyAqX= zjF(Ugh}n-Iw)Gi4wT@*`Vsco{oBkBq)1kuMs=qVbuIALOS*-1}Xy?+E6+EPP(7%{S zby$el5kbptJlDX}qX{J`Pv162&i*a%k+AVi$+x(hO@cesiR}lLS_p2@WQ9@wWh$)u zF_JjqzK7ez#VaXk`5x928(tp#CevD9$mXs*IQP2z))HMb%)8a5xj=u^q-+%odrF_* z5^>wsy$mZ}%`~i^W6#aAnNt1jWa{5dcl*s9FX7FUGKnu`Sy5PFP`>5_^1Fy#qq)G( zy=dmoo5k@=c~ofAaeZ8!{^P6g18O>*)Eb1pY1HjJE#?hQ)_E1?w+g#bOK6?UjQ}e#FyM~;d4sWu``Q}sV$##np{V9V;pV0P2gcBH*SW(1YwGRbJ4q3 zmk4g(Z_M^Hbnn#3g zJUo_BUJte##=9m^??0ZGBsj_4^GCI~$sOz1jJCO~=-&QEs(5PSQn~Q{pJ>`#cQK1t zgiw&8H6^vzZmFr8;8r+C`NxI~=KD%NlBw9Cye?5-B-(pzaubOhS}0Hm;C*AFei zrhTio4;Z%F{iFClTXYh_AducXjrm3`=omXBF(nK2Mhl?-CGmxlEF)0CT&JwXRi3 zsX{KxO?z&0IXZM3O7gylp?R-rGkLeKZEqv#@U^X)LlVa42QNInT0&nNiB)7)!8sXf z>&DfMMyX0#Ut4uLaOzyQwzk-#4xtXA;)L+Gi3PpJiE9;{mJ>s|IEA|raWuTKe>Ur* zHglc^1$0!v!wpKL>8@(C>i6>WNb*)LrX!M3e5&mK^x zSVfhDYZ{uK7Ay*l%ZzldJyUabwyf6n)Z;IFL#OJ#34>45ub{Zqe0y@!T*Yq7 zD?w`Nk;xGUJjV(mF(7li*VNrnqy7|dH+fx~usyH*EBiYc<}P$SKxr#0bLT@Fy_*z% zjf+W%W*rKUdK%V?bBcY@mt6{)XNtTzp=erC>)ONG-|CRTEH=_g?>l5J(F|%C!m;)B z#%sWEsZyimUg~FbW}>YoXW97Q!up=JZG1VaS^ofQ&m%6UX?Cq`4Z+D#9F`LW^Q9kk zm~Cv#l?=DcPk55BxEI(=v=N3NM%fc z!kl!7s#u+4r27?lQ(EjrsYPY2=^D3(?ky*=yq?ZSeLg}XnWQ<9Wr-D?Tld)c)sH+J zS2XEXqf!@rMy1Ui4>uE8-*^v7@U^t}E8=|~;>K&6A#W^F#ViP=-d1$-;Q_MSobCB* ziWoZa%x7Lv{nV6|{eKa2MZ=e=4~KCzlyb~cS+6yTmJuVpAEfLm`8X7B~L2W?98fYV9qNe(}5)Ka4MQwToq2nRKT-2iZOR&0yx%>9 zuOm8x%V&!BCCg-aS2$k|jVk`u9d_pR7gn=qrk2qmEaXCg;PcXQk$FeS!Dz!0aHW7X z<~e&fx=~*2ulV*hsFhdGEy~ZYc#`&enf&&gT{O&(0=EKZ-pv>#ww7S7Jj0x-lapJ} z!_kCSJ4r9Snp4B#s(ZAl%hjtdyuaWnrHfaQXVESEL1CwEKiSRmJTGv?gKvo*N89rO zyfTg7!fRN2IZ4X=tIuLFIC;{1uiu*ZxqF)0ji#10d!0+eJ`umtyhC>@O>Z(tf6*t% zF@2kSaYt^O^3sy6^8Blf#;$IhRn(I?V5Hx}CF*T!J|FQ8uj0)fL}*)4)1iCYyLn4R zWitt*CQD%&N#!(-*_APk!*Ki6j5Atzc=Ou)%)G-Xop`!@*1UHl*Y$4}OtWbzqQY+N zWwM@WjnAKH`^$w9MC=kdJl1swX5YJ$n(KMQYQpJqpCyFghli}@<#_V7_nRIh@dcKZ z;hj6d_x5vM%d1*s%v{=p`&6bUo@2B+r=2$CRg922fNRA~&Tgg8v!_Ndrx+#hql)m? zh7((`OKhTzp%qx^;IbL&~E6j!#pEtFN_v6#J@eq|YqAL75n%7J5 z){i!(64+W#d#A|LVLX`~B#8r-=r=Au5nb3izrJe!01~=6+Po7-(3d*Kjco^=aj06u z4{0QxG*gdqz*nx>jgJev@qU$U@tRF;z`fR?W`x_+D?pHgTp5+LT_4>A}NDV56;k~sud z9w#uey(@D605rDw3zXq+^mo414dvdJ_bdIT*0*z9-NMk6Xc}lC7der>)xZo{nM-`6 z@&M7!qo>b(ExKCY)38Bmb`op4tHottu{F@rt}X8)wVpM!zlPZq!yx-Qs>eDkayHhC zj(F#a;LGbmjc;i$bw0bN`maW0=(O}Dn^&>D@ujWxtEBM9q}>!*0Yqm*CQ?wta5-Eu zV>rp}UsmR&s@N@U&O^fpEqqy}U0JMg>UNj0%Y6f^VW5tARiK6?gb)kDvSa5fv4HDb z6tual^+@_Y*&&a{`icW)uRVpdjw6mwwzx@TMR{fa090Zegi-TnHMxP$Y8JY6*Ze1b z5Sl=jTC7rES=x+wl0$Q7v9rX##fz9*b~-oKf{r`l{{V<|Rm5qvg@Flf5#7q`WnZgMW)+6`@4kF zWQei>EyJ>i+wX@|c>^drPXi>1=#5y(T{3YPN|a@3F1Am(=spY7HOmhV>bkY%w3E*b z>)JzG3lyn>p)!Rm1?=tFqu3<}`5~)4tsGMyF@1&ueUA zmraOD%1D!T6f<<$%8u2yHPPncvX5g{H-8a@;Jtq5R`I31=(Cc>*H_ct3#-`T@~!8& zF^OYDX94DQQ6qVub$;mG%O8c~I7V1rWS2EL#h+)EVVwnQwwczShjzl=6n#QzE@C+| z%?-55+jjY1x|TPMT0MhnC)M05`PeasH6IVIUh>%BbZKQZ>PmW3F ziWhc|aA~Ksks1l2MaE@k&gnM&)fpU>74#etdf1w{nvGgc(qD%&HbTH4J6f%g;*-GyK#3c>C35VS9ej{Tkcyx z^4yuW+AJ}nY-YG?gBr#&>(8}xR?TR_38j8wDCIR}CYwszl=X`}V%t--w~nE!HPfGY(;(cQ19TN80 zq>jisE!xZH`2sM7Ev_Y9(HFzvLP*X4!+?7D6**j+iqQ6bn^0Waou;Ls>Dq?onldIU zuuP1~!yk0u5Uf``ZU^Ey-q7jd#kJcQdwpfcb3u%ds!rmK`4nJNfl*4NJlLrd7EqE zb6QH3Xj6){H@WFjcSddAi)XDtAk`RKHMZx{r;w?VDJGSV-Grj$WVbj`$x=5l#dUjE z2_;HA(Rx2YI(*xj_9Ila(=G0NM{92+dW7t@x~0dK9ymgcg5*LYjhw7|epl>wU{;vS z45@qYlTo+8pXJ!|YSU@xXk4UoTAA#w?WKuXBeT0AMs=08I7nlMENo#D>QBE`t#|wx6;~NHO{jH6U`2h5%X2#^05ki(o~Iw_9@Bvx{A{aN156D zH{9x|?RV7hZFgDMJVX7FZK>)yo#wZ3an6}7ua$3ZvY#wT5LNx;+m9Pph2p-Jq-iUA zC1q~slNruU^RmQ|*?42brpoHZJB=PqmfD4t+WFT~M{wbbrp664ut^c#2izd%918Mr z`F!y){o87ydRxEz6Q&haFL}Emw)*YI{3bpbl6aMGP3gCjQUKfew$B)bD|NQp9@UL< zcN7PO9PP<#D6591+^-n5@V@)E^DdTUPPJ62w`IBN{vy+?bsILZzl2=a`4?B0Hl(tN ze#vgn8kRz?KYGe|Bc&K-w>?b5;75!2%fm0>eM%1w=nE4;f2Q0)adh@3d$}gHl-%K? z9%P$?0I4dX{_Ny}2I}gkQujPZ3vOpYu3bs4&*E!ay-QHBykWlf?L4w>%xcqt91ALK zS+Vk>_gs{aLvP#mkF5mQt z0y-x+3JI;KVeFm55sQ4uu9_Hn#-Za+9Zh91ut}Rsj#rLrdw(L|?64m)TZuUG^SQol zymrSmGp`DEa(277&6w8rqo)4=p|^dlUc;+H1aQZHbuI0+)wI?zZ4Op4V^Io^F+mNu zA?L5K8RBUBOI&$1hXjGJD?xz-xqs0Cr@z0NSeJ{gWrkQi0XnKvvjpyW*^sk+vio{~8)RlR2Hw`;l{ST z^t#uv={izJs_0j`1h3`K5jR>~yngIIDc*zgy`}O!EY^#m zh;APY)ze>ze^1d{Q1M5Fv`HdmI(@(Po}n0E;wbIBu%H#-mXbY-^{)J$9MvaLJKjf@ z>RJtVM{D8@7})r3;l`bB4y*Q?Xzi}z%n2-)cL?%E+gEZbD>nV3Z&Ql*t5Q>ghw~$X zP*P1ZgwniIeEQYh{F+tKx4Vg2$|Vqdra-yfDU$>cfahq(rF@nzCv`CNsK!?IZQtg6 zt|K3ZaZpoNj{E-rk#E307u5C772n6G-3v&b*6QxjEy_)^&zdv|GRYZ+SnzOTWMRg4 zbjQ+Q=|v@N;}svc^)kGDEJA+H{_T^v%|}PMwbeCU6IYUJOPhO0EwuaS7)=BY@;tw} zj#dot$rw^%b}t`A%7v^kiw{oR@pf+aT@R_s=uXmfoMQa?k@$;RZA-&O$4Kzk+2^#L z${XwJtB~`?*DNBG!x>o%!pkX8cP}5q#VQiQLND1RtX`yJ=UMY9y}N98T7QZ3Ta9k( zLV{xYm5P?QjK<*r1wq>(0T{0J$Onwq#!CTKoj+>+33om&bedev8%#zkjmW{H|JCfJ zeKSqcC)Z-trfbV+o_Euha8cw~)+LY1^xX01J&rrq&PmjDoOylTXQ|Gm%d6QOZ-#Bn zx?RFRW{Tj#!1O*;F-Cv%8ug_ukIZviLve<; z`D(y}%o03(dQ)pv=6YB3 z$c9McCCLh5=(xx`kIi02CbdTwXT#bD;MaUZ;@x)UG340jws1(t@nnq( zOeAPwNYM*CqBd2=2JXg|A2OXusI{Sl@Tw~5o}Z}d9uxS7rM#l_rjc=Ou|;*Yb7gzy zd5)I|=MhN3QGR@6ZcxKK`m>GWVj}Hh$Mw&L{x0y&volE)T6UFjY9O=J)S0yAc#8i3 zt==DI^$oO2IP6ba@-dWDDc(ucw7PD0(8OL`s?kkb$kx%cJMC^;Xf&A~X1815@bB4Y z3Qa7CF79Oku&Oh$d1md#O?g;s6-x7x<>gP2xjpo@i_G+E;$uoF-tBW)Ew$=9<67Cx z;D|guq{8=?BH|m{3tMQ<%WY+7R`U1D`^gl}{{Sx^HVY25_06TZ^HNU76Y%RASHtad zU5h|{PW5D1qG`%WYGjD-M|fM1B3H|2FQ`F|+d<${gBE-)*@uP4s>9WX4&cwfCQgK}-&Z=L$rx)Z!;$H{+P1Y70U2Zw&xU>s0%(j-k zZW}7B^Fb(gEwiS3W~b|Kul4v5D5Uo>N5c(G{55y0YGo|$ZJ{#7rukc@ki-t=eYi-n zsDAM-eW_8!UbJGB;@+>KF{vkQ3L1BVVzsu@wT)g+uy}7$x_c=#DA#+%BuW{`j4K{h zzFcQGHTJlf(!$EEIO``All;yaFr4{h^wpE<{{Rz``^FZ&Do6}p*~?t8d4f~A6~hI;e6+}foJ&i6j0v(;v~cP(Wtyb1vq5|j$Tl~`>V-TYYT z+P(^{6&BKZiJoime@?NVRJNAdSme6CwUXZM*%)sE5$0RY*yy{TXFYN;UXB*=rkuJx zK4+nXe(jGq()1m6C%W+kuAe@yr?DZD*rA@@Nf9TX_iR^qJCtR4`Eg#>8oX3hH={?N zo8>ieRM#W4Q`DVwpB!oy@@p0`+ohBi%YK$OGMLy$BD0OOAG$^4CmjQr8mNt4+Fb1hSP?We1=cr;2x`(%tA` zO(&?&0KsoJh(xnGq?&%88^sf;C9ZB5l}(uh{{XB#$8K?6EqKe>zwb-%FB2yv%VVJU zo_u|*=<#XRa2VbxW4OAtv$%NfXNO}kj4)P1k%NVE&uVxaJsJ(lPgmULg%)^jw`=0- z9avmzP+Y-0O7UBrRlLR#MgsY2^599ZNIvNAUi~>jOWfGgmBh8Ac(T^pMY^@PfSair zM>hgPiB?3~vH3XK3b4-njtT3 z_xvUKR*km(+-Hi)t{qOIliJ^j zwJK_B+1)F?rvlfP&2~RQjPK63^);iGW%0ZhdR3ISS|+C+n`HNs#A5P-&wjq~Uz2?HHo9f)>&C`8C5A8Es{#GyE1tjMU!Gy`YNS->IK{r5 zM+$daoc;Ert;H%nujI`(lVtag1W~Y2J>Tvv;Bdr-cKzVvkD9&w9V%(LQ`>8v)>%ba zz0p%w@HUsI+h~3r{?4+cuq(-8jmF%7(7GxXDwCmEOC5z&bM? zNI@mJ#dy!eciQ*-Q~Dm4rb}&OaPh~fgfT#5w~xy)+bTZ&mizwz*Jl9Z1J}1N!MJ|$ zxjtpHJh(%Z-5i+shvWYM56wQEt6W2=8RpEkmxwN)ounIq!|ff!j&Ry(|+rr*Gu-7$tVb^q-ZEup^J3Tti%H6Ibgf8Zh9zVXGV{Q4DXu^O<#c|fA z>Bh;cb-BB>NXAL0<=fQeJ|j)yKM-op)*3m`5*eP_eOCJN7!2(ONAL3LnNRNx#~2x< zMbV10eD8Z$#pCN!ZZMRi=*}C*%i*v1NEmo_b8}!IfJ-SdGMkWqPEn=#*-P>bb>-gM z+1|4EuKwTpYS7KJ<|<%M_2Bmr6Bje|NX6)MY~ zyD+DU!x0!ls+6{7)MY0ImqWSno~5Q~ zKDBa$9Yo?)8CiSUo-yE!bHVyIj3?GSM}77X@W{y=F&*Mrdn#aSox`dK=IrRyrg4{BgN%B}%MjB7=EvVRr&_AmTo@V<#JjC5UQ#m22A)vJfmqb6iA+QlJ` zWsnl31CC=S=E3cnoUU?o+M3lKUMeZOo@1*giROn-w6(FkZASiCe%*2)2`%mXlb2sD z*Dl*p;|qg~@&|hKv}?%Z2Nt1%x0*-yZZlh%NF@-5gT4-~cmx6RzQ$^6N(ax)=!j}@<`Ry&4>I9_RyLYs zdb@p*?=GF%Xl8~#En`HrSqg@lR$(CpHwMjncp7rU(d3)vk~wj8V_v5`S1M;CEzgTa zn7SUb1W*f!&83Nw0R$W2Sw+N?PlB?mNHX6$NLU^@#dRu4%b6VRqfzB8>K+u*th_Hb z_Gyvs;JJv$bj8iJ{3;qU=@|>Z$(lnRLj^w}!Q5$9T(a_KPF)^qk)5!AI+UCOz6$NZf)Dt z>1;10x*kQ^2rtn@l0&#UIv=|%4nA2TZp=Q12Dq!?To2Ny*HTvMLmbHui0^d=%UbC= zW@pFurjX3Qd+fF!n5;1ox`aE(*?d>+6FNh`$f#qBY;nk2_qPtr zqaSrib-^{?grjKK;HfPRCc|2V?p{F{)9&GwqaxmKC_y5sq|zj+{{ZsU*Lg)GWcqVn zq*NSi(ZeZDFGgCihFwoxiJmF-6prrJeOB@>KJMZ;Qb7J|w%#zY;YRHL0CXD0vxFex zv^1jSQfaf$ymZ!IWVO9tH&L{P{zw-}Pu|BQcTu_CsNC;IMj&V9{M$>IMM}I@l=1o~1 zmw&Cb9R>}TxR zN*iM{-OXzk*zN%-Bzkg7ad$CJ7)`3WVN`T;8RMUuJXaE@TB}!5n(r+a-Tr0sB#Rn$ zizK>AOEtNME3>-R-o{&oiQtWoo#vQS%Pqu*skq=TZNTT*qkx1yFMav`i=oczruVVb zSm>*NYd71FT3SJBu)~N7TBIqzbVAwj9H>z4a#Qbcr{x&!ib&Aqsc zYi=QyH&;tUk?oUY=oK!YlQT+UB@zJ3?CD83oQr49wnH`XRPXR z&n}N8(uG;#i*!~{TQDRsUCQ!DkindiC^U+^lJ0!-;fOUoOG}dG_U_@Ypk|3O<&2T2 z+#+q+J4w#axE1H(t2oUhu6V@cxP5dp{5OE;#K6iDMVH zQ)IKfuN#_HIcH~P+5zJMg?xqw+g8NNwk5yaw-~OM{{V(LGOW6FrqnFCdYlf2qwD&H zr7f+LA8*v{irm|*W;oSeH%1e($Uw;4fa5%FuX7QIqehyX-y|M~wV2d&l&RPETWzIj^Epid&v9`$XDu zQhy_#(e7c@yba;ItvgbCG_}5l5vf3{BR~RCvYTp_(?-1!88e^t?qg$5ZD-A|iw#Y@aeq)&;NoI{k&Oz&+;jbxhUIj}2 z^}AflipIlec zVJW#`bYCEp}hHlS{g~@#Tz~g^iS#%vR1z$<`<(G3qi*>%8vB#sR=T zd!=_yQcQ>v5R-;vMjnr?-ArD%FAm+upY0J20TylG%q zllF&Wx2Rrmn&z(xu9Zo}Jw4+&)Qlwr-@dMn`{A(Dv@4jbZ0uvx^zBeQa@)X3hTm4S zER)7ETm5n`%6shhuOlz5CwR%J)ULVHV@gjTn)*sDq8LW@1%oE?g7 zteQ7Nc<&e2{LHUn+;i$v_>pJ2ySlr(hCe1NFDq$5Jfq1h@qeSCZJ8yq zaodd7p+cJjeyMe|9 zbYSbHD>b3diKOjw$*#5g+v{^Q`hbc^Vli2~ttHFhxhoTwWJP1k6UjW_^{=FPil(hi zDBSWss^-(1y6kKC2f~+k8tsm(ZQkC>*co7+=ggeS=vfS?6+x5Bko?<5)i@dI!^p%{ zb6UIH^zgJ&mEyKNPhZy{(X0leJ;SWFvv1Q3w&5qZQy=f`rh_|n6?TqB2W~!L+dQ<_ zDeKNMoHaRh@fMHbEke`6J}%JiEXkD5pvwgETV2BLn`4GaDECpel8cj6$ zlQ`Y8Wanh8j1pBW-!m+T$&<-7KEd;IBe7zs zIP$#;dWXY}8%*&1--)HUu$m}jnr77@g(QvaCf?k{;#8X9+CZZ$Fh1!Anzipc9P-01 zM(%ku{wdXUB(|{8Be{b&0)4m5fmX1hLBH-a=MA?IBN>130X4HLVq8d%Jz-nSsomTJ3WG01r=H zf8ZVc=fsbPI<=$&SzC*B-qKq{k0l>r7w<+m+>sK@6G(APh+sJ<4Duf$0>#m+7% z?V(S^7CMHfrNa+_^`z9I@jTd=UAkOvOBjrY%DIqkO}T*s?Se{-k zoKjMYxyX25P}c9XlCx;qh5KofHMG`|UBH%Rdq?>cA#ncyBjXE_zL^-WD;tM|D>UU8 zxp{lqo8fE0EAri=XTlyFy3{qR9Zqdc^vz#Uv%J+3&JiDzZu0qd`=gBIoysxZ`Ok5R z=dXx`DsqC4JYeGs_gm_5<`|hjdG&i4zY;Gs19I9e)zQ^Iv-Vp^!4(V1a>+f?h28S( zi2&mm$zIj;873Yslc<%s{(By5cQfvFd%5(amRRA<>du!st?D=15XBFfYYa{u&>16W z#{Hjo8QK zV{pDKV!*Jb5n-h*Q5OpqY>MH4Z=D(~R7` z)1Z?~lwWEwY8S6{cX@N8*k9a21+oS*HPnLMIJT@pHO4XX4CL}_f~?b;R?^L$gktRD zEpMTQ`k#pOjT=qz92cK#yDrXSnTa@qg^4F6bL@_mGg>m;|x5$iE zSqDiop_|3tF|m%`d${M>Gpum#u~Qt(-@%wBkmU9tkH)yFWxTg?gn3r)n{UA4{>8(+ zoR9z3y{^1hwpMyZg=uRCh~&9RE`)Cu>Eg7^;Usqn8FrIv7{=l;^A)cql{rSNoZIB+ zV^aqzuyKp{m5(m4_?s@9aeWQklE-uQnVxvw+9^~>Ukm|BqGiV3c_TIG`zXDSoyKtV zCZesZQd&E0@@19rbT^tD_YTu<)i0z=$MU?dG6jzd8n#^%AS#?TLgui2NUXlrq8tJum~-K_+(vdEbL$cPveVUhEJk(%*i984oBSO$mn%D{{RvAw^Ch3^G&{sPS&G_*3Qn+zEZaN6E@yCSKh$L$OliasZKDb z7PQm#KAN3L=+Z0dUJ}>V*5b&?X!@xV2<+oB+*}kRxE$H^K+}E zbLuMbHBV#6;-x07xz*@)vDkR0PuA}Rt)8ly4V-McjI-OS$V%&KC^2L&ZOpP^&4o~G>S!4;$^loY>j|y zwl?SeVz4}V4y(27dHG&#EJJFf9Y0>Ddmf+TcP-y~V7JaDyoeM=~R? z&HK&BA7f>Gdtjc7hLfX@h2_hs&6z%YJhbS`-wE$D?-U245xhc)uf8%gAkN_B%KT^4yrS^kwsajq^q*^>v%?$9Z-1ElKqsWDKFo?-3bpWAYF;Vs9 zO5D=EtD`b?JkJe313oKUTPV1mGWMm#y^~#*VfTqKFWp_`20CXTp7rh2;tW0R+kRvA zsc4Kf@V2Eb%R@5T+Fje?IW)lKQI=WUQNGB@#YUG%d!(|p$EiO{HXtr^;B{wUS7 zc{J@L++1oFmP9KePVq@>p+J^M=2F}u<@~o+0DpHp`EZOX-dwhCx+`uxw?6x}(3EW7(4fS&f^4yss zKr%38w}wBj%f7hx#6|xATeH!km$8yBY7*Jncza$mGuztDdvByOCerH=NNt$Mk{2tz zz|R@$U6NnFkE3MDT(p}sw9gLenw_+eTwBSaY3%Ce&m>4)TPN*1i~X&cF_~n2y+Wod zpBtOTFWo!}wcB?xymj!e#5&5_EuH19>^4xeQQF+cl_Vig_qQ`BJu#a1r7J6^d-Of* z9V|X3q+uz0C2dET9UO}hox^g;Kfc{KRhtyrLCQp+2Lb0QPFAYkJS>sb9KMCl*6@v3n)AiYIHM5YGGI>iX zTTE4^wsu(Mh)p2?o#PABXeTvm6H=_yWl#5Oub+QI&64JpyAe&`p9vPQn?@2|LvpWX zS}T>eo=erZR4VW^a{lrmCN}L*KaAqHtv9Q7_fvZMA3=o7D`C~>&8zN3@b^Hwi(1yM z^x0;b<4l@cNHrMYg&=5LuxaGEoQUCFvBuvk6W8S;kE_bPIIdeo+3&Yg&CF}h6IISy z$-PQ&rPOxsZEY+Kb*EgPC4-4z-)%pc81rKTdKKHq_3d0(q^Z~Uz7~d}|eqfV{4w}UGmOPWeu z4UH?n$42lBGup%Zxzw}@334J`-dnILyGGNJqadDth}X8PaQYrk4~Js$beiIV#6@jA z%rYwF_rx;@3Nk|M2wU4VjW>65)W=#BVNc7M`pf};*x*NwfoVF;okz^YxTj8Ys%CU)~tb@LQ4B+PWo*gcawaF~r~;~%K8#_52e8SPL$qS)7T(b@%+^vpK^%cX4twye!h8{ABukkyLxuaCWfI9Wz+r>&6r2mfw)-Qg*UDt4R1a<5x0kvDyoL zLr7J-k4r{^_IsHk`O)HpF&h37ywzRW1w(9WP!kbK=AOdF!nNjz04>`?AyX_Ki_LSTfvr6_Q)O8ltuk?s7;A?BR zW0&po#~hnvh)lEns7e5K-wbTQky~y!^jd}Eb-l@{CCa4qk2Ra~J?<+=R?<7^_FvyY z1IeP;qNG;ou}do3MHywxnIF8#ZhDTD;MT;-a^+e@GrlzA6moX+UCp4Iy)xkH7Zw0FVxGl&`*gYw*JMvM7+@? z7FKha4&br=_RdoKBxH4se70F5=L{J}Ysa1=>R5-)zjs&O^nFpzqNf*U??k<+v>qpl z^TT(O!4He{c;tfOJ;Xt9B}Eb#$pDzxl_X;^xEUDh>cz%TjbE_jn(mET_KTP8erE@z z_#0U8_MxQ4`uf;vnytIfs;si?C^wJva^gf*jh)ZTrC1QyuTu>*h?8&NMD?An&4rA-lv*_Jtlq=Yw=mu1VtkQafpkTI199jQ~D;Ga{-;>;qUi;ZYL zSxaBUzo+R^&Eah~QG384mN;bG>zQq?9C=N98)xo2mGk2Zwbw8AxviCE<;x@VIxpRf z)7Hq(X}rxN#TFWrv1wYmTsz*0$?}pgv7|&cGSMF|W>=nlNY6cbPBmipiRi+*8;O^~LPNIcox-?_%)~C$7ka)wv zdZhQ-z0I^us7EYf&MT1Qu^vb^uJV^zBR)j2{NxpHm_K7(j}oH!P8W8J%|GHdgmfJr zO@msG8jMa-;9A?qC)s8LYpjhNP$D|u{E3nWt#&DMh zI)o1p%cH8>qMMPmVo;5`FO;9XhV9QdLNMi;R!Lod!wQsLj*G&2Q(s;Ef(S?u;4;g4T!FMjwIf~$2E7a(9*tC_tt7g39a^%2IA0KJS9aR1&8>)>;_0lR zwzu-*0HlTmGc&1JyvZYNiP1+2K2mFId1i5tNbR{?#`SvJ!awVHFcKZ z?OVxpg{`A0^2Kqn5^aU~J%0=u>ZdEC#K%zOeAdwOZxMLM;zx))MXs)mb1Zs(op&vu zg5K>d5+sDaH|}NLSz<2D&NGgcg<6)Cu6h_;JULV4zJ}J5uWC2m1#4YfM*BaB-r`L< zE5QmRsT{s)Lv*piqs(P^T|Q6-S8>4Rs#W5txo=}9hH9r%%QX)Pc#p%^vFaL3ZF{C# zLH6rCa@%VpOBe=Ld2liV5(<&?16WhW)2|LmX#W6}?sR)LozBJ|4qnXy>x~_>R{FYH z-D=UtrcH}M9BVR%WoZm?&e9*=D(oY#H8pVVoGzPfd4y!7L2==~2xwj@wbf$Njg8v| za}on{Xsog;dA6rxDcu^BOnugFfQsY7SE(p9C(Y-x`JEJCuXBO;qvCx_RM*-m0z+#O z!6wKM!xYnq^7k80-fi+a20Y`8*QbVpOM8=wsNC+2%`VI}{+$y7Ap0`iIqn@Ck?)_J z52kC)uRB6-?Ogk8HWl;Hr?PP7`IhcH=u_=NSsksXmN$&HLPWALSo!`1$-wMeHG_hi z<^JmX&ZUQRV(Ld_Idgws*5{)9KeCq3Le#uNY>f=M{l&G0n{y(Cb&H6+)z8cZ_HH|s zA6ogWd}Ch~OAUL*l5&##Z2thRr_bgXwO+KR7o)Yl;}=zq<4DvkBp25=SCCBr)U24u zV`<}+rACC#b~`G^jN=D*B=RfkDNv@;IUp{epYrJ0pz5kOxo^ z_7!K!j;cK?&zq}Wl5&qMrKOI_5K5;u@rg@Lo*VrbT;5^gxsprSoz+|inciYc4a!QZ zgz49c{SPdq6^BWsWPCnlDb&QuNwnYONgNXSd4?P=?8OnJVH=Vv5^TxBdSBnG+#*mQx1e?6?b}Aj zM)K-?8AQ72T~|wsXpd96V#eJD2l`dI>=Q6y+q2EIkUf9jV8eo;~Ap;J*-fuIp9R zEvJd^p57>R8^o47aRfHySj`=~mlC^$1+qOt^IS5n+`Yz}ZMR$h0Fmg=E~`r3+Ab%c zT50;enWAz3bg&LD;c^DoUPnj zl`vgFscG!V9jNmpirsPwD{|7PEg)6ov2qIzgNpO(FKrhYTU`!(MKsok=(N~09d0LU zsU}T8luL--H7~t3yR4Cd$7tHTFjYJp8hB{?2=YZ)8q%d0#Ul0P=h&f^Cx5g`(K;Dt zGfagd4dh!zBx@K(m~)Ka6UKP1$wAFsyBj5KiR47Hyj?}El_E?9v&)Nu$r+FAn^^gB z24nZwZsQ)65smb>%xuG#Qt(EbcJHahqFI^aNmBRh-dT{d5j07;71+iwH;i(6XNpdY z`Znw($hWaeRq=O*ZtXQ&-7fal`p-`Wo}V&z(-@{vh1s9H^^`(#I`T z&YYCC)0FMB--}w@LTg_Tcy;geTgevU(533V++=_;434q+*dr;7IOmdUI+#@@c)K&7 z+sSCr+&_mtAACWY*IY|`d+VVL9!=!wDY%S7Kks6>L-H3J3I&rbo!zUA)SW#UqKssD z-m&oONY*?}c@5mxFu^9FI?rcl$qlynjL8!$Dm=6$E%_=xop59GYP4f1MJ+AA$n&eo z#XEO8jR(Wt4e*WSt%jd%?O_>7S->rbC8} zKX1wV$-T|*244M}#8;Y}wi3;y>2?#n<-(YO5z8QsNl_(a^ASu98vt{jfQs~JVW#2C zp0YFI4Az}m$`;a{(>(aWWY;?V{>ZfJJ6}5EPtvBexVVx?q?D-nViH9H?i(9>0g>Mo z>(h%%UC)xQRx*C>i0eKZYLaL^ACAjYw3Y}iWR~I$Ml>yK(z##Um%z)RVUmQdI@izU znRKhvRU^|&ey3B1vPv%3dir@0Y6k8$(e5rDNS4n{j!PNh%u_;!INDu~m^t%9ei-dT zinEM*&tEgu$|%vRDZ;dG9!AVrZ)KF&&vLJFZthxZ%b7|BCgXU_h`jv8@J=ybWru== zIK?dy@-C;@XT>fnJ4+nTx!&+tL zpZ$fX?9?TWNg_A4$kO>(+qwi(8o(GG!=pYq;2Qb7ZZ4$Y)ku4nUkr{~^`%ouZP6Zq zBvVax)|YTG^Q2ev#tJkRpx_alkKYh^7(J@-Gxm67qo+4QYCAz3Ka2Dm`}+-A<-W^g zle}qhd2a3YfgE#2i4^FsvQLzwVVLdP#tU&-W->6GX{RlI;_%fPmWMB;+TUtg6~wT? zB!nrFI5gO8qe$RVxSCa0d!6lx3M%#6(z~i);Z3%ia`Qd>K0c(10r)wYdz`g~UBbdfx!H4M8(JjO8ZV55dL>0s&d#?9UJJVz+Y7g42eg%{z!)U3viFZ>3C1@@B%U*}T^fBN_QX&2 zyM~puCAjldneI{nb>@JdypQH>$Q1{d^8B@xN-v#BF{+%=*v0X8{3EHQX_|hErHQp$ z+gPtBm`?Fq+J-8{f=I>~+F}`c4nDQhLMb;ZS((?8$i8hE{mW;qj-vGUr}4B zwGnM1G)lm$xP_Snu@5$EZO_vc%UclQr7LTDBi7-{Zx@L6a`+OvIh$2`DVpNKS#2)e z!^v|5jU0@7mt{XW{{VY6=PY$b^>yCfCFe z#c3_hl?;e%u8CxoW|bt9$@31^k}?}&$hg5hD|`iJ+l|@7R*W=lCUSP#PlV5oY^`+L zL>941F7EVsAlq`gk(HC|^R!Ck<#FB*70=+-pN)0W{tJ0>XosUtDXrq?adyPL; z4{D7RUR8zEQ0-y}9#mnwAi|!Wg1o<|S5a!qUo&rO1aiJQ)}z%gtu%1Aut9@=s9WCK z$!w%R!68KwsuI3qZ+v8YqPX#KsfMFx@k>Qx(#omAty{ffk2JBj()>~4y?ylp(&&12 zpEU9XWh0L2=&En2-L#Rr_20VNiRhw{{R5I!xHMsQIEpplDGF){1a2c zo*k1-(X^dSoq*OF?gJn2A+=-*RY%IEPcA~(>-bj|ZHZMSI(=z!zx)dS0G5Y-4r(~5 z#df#cHv0F(Rxn>#>34?RTTzE_jpJD(w!9AP%F;*swPr_L`Jiv@mgng*d{U{0jrZH` zK6^Q#?D10b)UT=?BG<#Wx^;lKhGPVi-I(6@$}X~RXOKwE=6RcNz^Uhw_^)D;jA|*h zdo#(Z+m9)C!8+yoXt&x}f;lZ7=$SH-Hcaars9ocdJ-ZAL*?h3`BCrLck-W6rjLJ$#2ONhuuaCy$^y#i> zK32{Cug`O$(L6(;-9Q=@7Bfg&eT1kWxbp|z{nre~j-xrRn#N%3Df`-^hH#W#sDj&6 z(QhwXQqgqu)Gx>hcQWmUc$A=I5_!QJ3>O&u>Z($eI()O2EPn7&Gxe{AJ{0j4w2|t5 zZ1--?%X}q&J`&Dk+Z$(SRo{TSdRDaaTC|?t?_$+yC!x*j8c&0CZwlP$nlnRpeG4SF zlU@g7JT{K9y}tP4D0l6`#x{-FCy;C1!Pl!gs#98aH>Xlf>Tn(>(e*tR^ZRE?b{3am zt!*SK(nmZuod}o)j6T8@_mJC@aNUz%Lslt8v(>^@l}RdnUWnZAeZ-o@r-{5i>*T(p zW#`#JxE3!6C`)bN7X8@cu&)JEw=BHRX08T!Z+4}*o%BxjHoO_8>yYS{5}6{N_f~n= zP_VsbdwG>%f?H^}0Q+VzyKZtDcG3=Uk-lj-(Sn=4>s8S4D&pKG-M!b)$kY5$Jbodz z7%!p2a=LP9H&RO17UR!Yq(qh?6}C&XgkZoRBX<<)<R@O(H4qW!)VSK^23dZ_xg9QjKfY}0=B)*6wf5_1a~(6C)X^ahTrVkmASl)C*N-I zo246|@`=vFw6u(YaL1bZD77d;SNEdrroS`Q!bwj>`bZCii}*Z_<4}$%Jf4 zWG*E8Tr)a<6n@bT_sf+MI!X>Vw6E(e_JEBSB+EZedpKQgG}3tu;f#8j({ zYnk%i>3JN~+~*{gry)Fg9;K0d`ut5K9;XH$E3I89;9spxW3lzEfT^RE_od&e3Mr=-hwX!2?ro68S}W=eXZ8yVS1GCTsqD$1bg4)70%SvR3jkg;Y z=GhaeeB-t{n)6hXZv9W9g&FcF#dAvA9(UqT89nBSqv`Y7t6J$=yjO!zP{sy>%m>Pe z4&&v;yr;~=fCd5JT?{`ZM=Dm@SjuF?!s#N?aHIe1S_>+^B6@Bn9M#4F# zB$C*=l^pjxU&DHf_;W>?&i>-(PJ>ppd1iQ-C9~g@g#SbvtJaNHU<-LHWMU{N-_*78cbrG|M>hEP1P#yI!CuML35&RTB_X__{ebqya$x3Rdp`z%oE7jc_{_dZ~ZT*Qt710a+#nTB{cLy~LQrBynd zi(4F({{VGPRUVwG=8mPISlvw*h8=Nfac@2IT<3M;UBfI&E)1>J&zMUV2X{`D?K)AM zc{(4S;4^$h8GUvx)nhw(IQBSrJPw*Kiq^|jxm&nz^x2jhnUiWmFy8L=`1uoNFcmQ|HXe+}Bx&7Eh6b$^Gy*|z>D)h>q3MLyA|%B7*y zGC*G{-QsB7LXbm;B|~*0yvlK`+lNGTNyTd2naKP!@#ChUsa)&6Y=(QQab{1FE?O&f zkf)w^C!EZ)FYi|%r=3P1(B`9x=MQZ;0)$*+>IBJeIb$(m z%R7l7U5w%04a?=X$h(MMc&^&HjVv{xqKyjlW7=Og0rs1m6?dh9Sw71s{3j;n~g-Z<%{j-`WGC*(2S~K z)#csxG*dwS#kw9TO+x1PU(@qESGOz~LZ~6*@1mwIzZut}!fJhxFM^tYJD5;~R)Ln5vi4wP1fMLVn6A8moD2SzvFl+N)z zg{{t+747`%73H0Yyf>^jg}c)vYiUbo1(H;XFh}uYBj&|-)ukGc<(ASeG-Fnr;Vq9m z(rmSXr#0kPvM#NzsEY2&M<&^X*5*mP^}));1c|pChB)XdE2>y(NwuU-TD4Uudy3JD zwU0*d{FmM!(PF;3ac88<4WWBGe7(b)8)b!j$&lrD?ca#NY!EkB4mTQ=OGSIftAxWw zP*Ri8o^|mH!8$gU!|V~HaB3sWJ|B1UB}Rl9R%|mDQ78_$&j<0xZW9pS#&g!A6?Gn_ zeY8n+8cU|DNj&8yd0sf6jS?lnnnz`gUPO*VwM%7~=Dj-A;RT`PdY-GM-A&=xboeZ^ zyT~kV-HHihw3aspCYk4H(n7)ZA!D99aogpqHCemOU3&e;wS>jdZ73~Fne{ie@gA|G zY8p%4>9=^*=XkcvVM)jgl0~21Z6G-EvOqoYn#QdcD8{5EX|H$I#8zrEwTt%JbXT^q zPozki#*!Iiwzo-{E}$w#{{XRFt0N;|<72S&-P*b6;wKsEy`5g`XX?LGIl)OBSBLya z+Bc8&X4!G}S!R;sTQ_1ionW&BpjMEfYlJPC7nZ^A_m9&!`$#7yoUPC(R*gAwrg~?C zHN80|y74xm;cfK?`#*=`3-d#19AV~PE;f-OEJBwj3|MsOU3hwG3dfh2PE}=Ov^o7^ z!%)%C=;Kj_1dd4N)30)t5=&%Y*Z`J7s?sC>0IXp7>GG93Yo4Vi8M${oEFDKu7Is!E z-D{o~zwl>?FXfqajb1ybrdTZ-&Se&f@|dBKkcc-6jogjvxQ?Q>r$IVyEgZPIjn-D# z9R8zs;-401*V-btxF`3Kk{Dx* zR&vEza<%V0chUMizD)P9`J;TQNiJCO-}>9sg)A;@Baqxm+J=&5S@jpPk~vh{J7z(a zBH=dyw4QsPYHJkMAl(ZSy<3YPIv+^c&{!PN{VrkBH)UAc8n= ztYFfZIkjjU1(ZfZwaJOFrAa+!iX_mkb+`P$fpLB&@0V=att68)fE zTajF=tWwZ$z7zMQhT%ZkR)dMT+n=ydvb zh`dMQ*o>A!Zx7g90%CD$XSpa&-OV((woIJxfyk}v86@Ho0UX!HMOLWy5>A&d1wj1{t8uT`&xeXmp$q)*;Q$4V_B>;-xBzV zbujYUU1^IRr)+HGA~7`g7V07j+qM}Zm0az?-o%>Zt%#KfJ3gPIWYx2uskf-zUt3;y zs?9GR@6MU6W;bqSm|MdI;aI%ZY^i@BZ3pGUardh%4S8ZHQmH5JN;fu&?LD@ZH=R?w4EdJuM3^Eq92 zT++mFOt+Ehy2Rx9a^5(U!V{K#jfIZ~03xd7*UPW0*PC^DqfR})uf+Mxw+D&MaY~(8 z`#AO1+8DZR_P?V?I>PYk`d!nt#paQJ3T=_w?>tjR7D%MP!m{+Ps*$Bxr0)sEX(Zp` zp6j{#T}}~nBhQ7OGLJ|8W|qBsrJWMfT+xY>L)BQ?{f_O!O>1~g*R;4jO5^56JdyZS zW!QOD#Hus2YNoYINk#po`mTp9J|lGS)jhO%!T#_rN*x=vvI4X+|8-kM+!|O zUSl=Ynz0K5#pV`vU7-P0JRG+?*VpHHRIqYTPns=W==jVIXYKDfM$GlAN%VCQi`llo z6KX+iGQg7h1CG0n`nbmx$UIFGv1Gy4G8Xyjg zuBbBXO6M5wU6XEcvjuySUs~9kw}K%g_bfc7vhu#!aB_sPS!BvZERlxdRwr*@aZ;4p zLuC-tqBl}T3OD-L#EQ=Hf2+7wW3-+^R+*O%{Xo&V#wOGTJveqMm)QB-jXaV<%4YB{5b9T<8sn|i3rqGbLS z@SdA{;hz%tj&M!Yj1og@V+%(rTEt;HW`8qsvcKI%PE>|D2d6yiE2yrgO>)>6Le?v}H0|93gHq$jBM$gmgz8d_z?yZmhd! zYkD-yZ3*|l(f$TUF+93c3v6& z(vMKOWPL{3IZ8r>WD=uXZ{CW6L%ncLdjnpE8m&iV_IsWdYlOkWnoY_zU)g(|zlJ;w z;>{KAd;tD4(&D<-(Wcar&dytnMPLyK-2~27D94sCzF-HbQC@d$G>6WU^u1ZoRxsl`%x+6)IFhdk>6DRw*uPYDjA2h0MC+^3x{{S|6cxO@)=cl?y zA93OL)9xqJ^J{l{H$xtw0J0R-u%?8d!tt%RKGhd5R_Lmo0EZ0DZZQz~a1h*eDDODc4 zC^Y4TrBPkS-YPhXkh-~&_HAiuZ>|+|^tMQt6vT|u!b3(FzVDDoGO_pXSyZ7F2A+z- z_N~6>vPY!ey^Xe~aeFj6(AnwIV@?QfBzje^8UNZd>EEmkczh&U0@5(p=u2M7l+__@7ET9A9U-mrGllwt)F^Jic*Ly&aYbxazI}J)Blf zSJj@>6Vly9kob8u32wCuIW*r8!0zzh+FNh)WR|Ou8h*KdtKQsMnPR-RT~0D3+~ma+(m`w&b0~=)Xxif{zc3<*uYcrum9t305U}!1 z&*HyJ8(u1k?(0`R9X9bxXFj%)rMj?Ioo`|?E99;tjU!pUVUk;>F;z}oe2wvSzuIGm zOXByh>Cpes=yb1#x~#Tl{!M7b4aAd6YaO%;JdvYFSP33OnKtL{s04bPSIFa`LDhGR zp1t%u>bN>`movHK{v+3XQ>A#u_eJ|+3k8w>!>L_Bs?x=PS8v=x-!KGr?_KLE!zz6I zkI^%u1CinJHIyYTMEcxw&8S{QYL|hBkXl!n*%_pffnS%)00`G785yo62vcptOa2Gj zaF+?s2a1(>q?Xa;clnS{W^ZmR^uIP&iREch5bR@zKQxk}XKIo_$;E9POQ#1Xvi$oU z{9^FfOf;$``|6fo=FYFjddXB9DV zsHaYw=9-diKTDn`3}WGjt?eZFVJO(aH~MbHlkKo9N27VE&+A;v15s}levtD_J6Ba9 z_oL9h8~*@nCxUfNMQ&}+hpq1JrkV@5n56IpS927}pOl@+_fO0?uIkj);+nLqx}TP2 znAEX#9A7jXzD8D~q}^(&nx+2hy>ABK+t2&u0lsk*aWN>qP{2^5oM8Rx@~LMWwcq^u z+tbhHe62jzPQBm2L#t{@;+;2F9}|Ag-O413jTLJY&JTDDpP`9{EPQGH-o%c*#U2U}A6Wi(+C2g(|TEgfD z+KUkd92JZzlngms;L@#%uZO0m?D^?5w)mEZH5_jwlF_KU*zUCt2kJT(!t-aS-otZu zqRIB#3xL81*KC`NJLTKBn4U!Wxop?TQO3s=kCUefDs^MZ^y}UH%cY2LtL=R5aJRaH zx7f9tAN1V9_bvz6odD#&mK#%LZJ=^%d~(ySJL7u&Iwv4%qnTE%&iD` zgHN97;nGVNNFt6{FFWC|Jl>10_1W9LTNTemgOD8{1qwMC~Wy$$Gmacr8s zrkSbT#da>P9F0I)$p!V4jD*K<-d@&_v0a308R~fAxhvpemE*6GeBAm?9mbjC3uT?H z((r1^KH)KalK%h;fOkPCg>F9Z<}4rfE9bFUJCe~^ob~YOd@R4A&1tCI&#Fgeu*g}9 zT|+9#=Kz}q^^E6mU*U0)^{*opMo>x)TAYq7yL)q{UHD@9XMeF;TtPBPEXdI^Zc>|> z2;H5>)1KA61t?XDPUTZ=Nb}3@59pe<`>Aj&Z|_KFww$~c`hqH?w$erOLHo%wBrarpJ*|9Iut0moBfUUs`F`&#cK{@vSl;;Svn zV}_Kad*5PVOO$uSuZTVhu(g9nz0xDsEpAN7Ew{-WQ7x>VM5GoO4ySNHnB`9*y*kyD zZGNYvg3IdSRJk^SyFBy5`hA;Ed~|7ImrT= zC*{YRh@&2N)6kqXB-PQ@d_KNq)wM4U%{aTYiWu%}S~!?mnB72_Mj52Q21Uvfj^nL( zxvdoy8jDSA&OBuvSzR3krl6WMPyMTNVG$$&Z($iy8+Hy<7H0ndSU-eyuR5hCKY>a5 zoKI6)-ulN>vXjY|d@foiAhMj}<{3C(aBGsMH8-zKOzmcQhs7xDbgvCTqFC9>6|ud6 zjngo7l%y`?CRn!N&vH+^t>%cpC3;BFZ0mE_%pBAL9L`(mzg!y zpPeTAZ3Li3P>P4}9`T65m^Fj~6inQzjNgkw7JL)Erk;OSQSdhN(^xa;YA4 zme;Z2HrJQ-eiPJJ$Tzk=A(YxI4={=ry|syES)^l`Uuw_1C}FsPxZq;3p;5vu%Ud(p z%&=bH6AD!07`IM3ZMwO!;b>*mEHwykZU&R5&jRT!Z)fGrcXM)B%=dFoE89aGvpEsx zoxdus25PHfp)Y<<%<(GWr-hWL%S#P?N5tpES2Jo;KZ!NnARRpFceif^y{Z(;M+#a9 znWXI_?>!IJx#y0iqMJ`rXvSNu3U{6x@n?$V)OCF&qrHM=+~GSLVE4>id=SPlrA$@l;Z2V(QaLv-|I0*9GL0V&piE zHFQv<;GPd^iDKi2Uh{IfS*~jgQ(TnePTh`+!5No8bqcG|&+ zL$n>=baG8t&pq*%!);$l@OOu`JxcS=7ii?br*m7oBAt!6g~CRPr{?X9aa{DVYI13G zG+23Z-7QXN+uhn&+u6qQLvJjKvfrR&0NnoV`QWmMn;iA$wOnc5T<_4@rBtb^FqQhd zcmDu@ch{HNO{S@%UE2c`_U$W5q%V~4LpCjBf>2&ErYMAaO66D|T6G?}8c>T+lzMJ@ zv|13?^h=#O;EyL%f@l&v1`1_TRg3KfHZ)s-&dgTpXiLamD7sG$k-Usi2K?KEoZn$vhsTT4$8TTLL8JlbvZ z7^R98IFIb`#Nt#C@AI~F8&5hoFQJj7f+^lO zV}Y(qlCjCPWm4k`rMqV}rdwJuttBO6$l@whr-l9Ay6xm~5&TioG@lmU-AO$9y^Z2S z5x&@vyeScKe2A2O@;{#^?vi?Dy-4DeXRlMosl!#OVG`1um)Yw1x|Mu=@lV4u>N-BF zp-P&I>06|nVbDLALkOFAPOBS(*Y9vBtx;a-la%FEAx3oS=;Uyo6}+<=t+HxbXm}(p zXMx&8jyYswBy8w5myHvjEt}^Y4sl*>Wz4U0?WtC9f`UzV^F61)9}D!$+ljnGs%i3B ztbq=hVo8i31)ZdOa-l}TKt*BOc^Nh1*Tr(KSie(FMBUlXc+gv?j&H2uMUv2J41A_l z#zl(x!yPuO5CN)-moB^V{x?1Bwkwi1+nxQ^{{SYxsXyx3KXn8eB4~UR}Jf-dPL~vB&036sp~@8*UF# z^shHI!m5-U-`KUkRD6FH)1cs`d(?xrovwHGIu@y`=)Nh6&B>LbirO1}powITF*Ilk zU?~p#pF%oTS!9%G#WnFa_a1ItP0oY!xyVg*tKHsPCGDI#ZiOx2k5s&t;U$?Ow~>s& z5i+CwOLB9?Rtp6}6|K(YIP|r@tqR`()zT69vZaUDa<_}^Cz)`& zE?|ptGf2*!XO?$xqa!r{oQS}BeTMNPu# z$-#;8v8()YTGoKltJx;vi)_>)oB{C9PCH8N3=Y#i-j}K9fECt8agK8?V{gGP%sE;eyIl zc1G$00(#e#fU7CSICa)Mqts$ykQr4wU#y^ z9w#7_f4v_dabH7`=8m#zPgt#d{LfDbh*e|DCGR4Sh;3~3uM#(jJYOuDd<=^4_af%I7<)D_@~o;$MUG4-RN+t4}Bv@j17C;va>qbzLJ*j^=r7pqfV0=0z7$+uUBGqfE~$ zIQ`gi?7NOhA1dIJ6ympMRw7POx4d&j&Kg+r-CIdZ`{)qEZ{^xI{7dwy;F5c}1{^aqVW5&5ZO$4bxg@9e zw%37(txghd7q?e`cjf;80PTa5O61-g(j<$<7rHIPOBDB!*v)hUE6Mg~Vr}MW7XZAa z6h1il`kuAPUJ9#)NVe2@zW#@=fSsc?{MP>ff^@n*zW2J#&xq~>%c3evZEY!yo-mCn zA{h1tc2@EXjO1+_!1b?J4+zCuuT$f=ix(QrLM?MevrEKYCVO2GZ|y9a?QZu&8p=!n zZ&o{;NTG_AQhH{sK_5AQ!h1^Gm$OBW1jPlVg~pR>I^091Ts6EiDB!Cq%nv^Dn(*;Z zYOgi-KUKj000!Mr=AJh2&bHng&~>dRNIH~DrpRwz5s72EG8qzKgSq_ar3~r^%oA>Q z=Dj=yDm>L8H@vj}0Dye_s#>IuD@yUlkFTtC;}lCA+D)8y5&fFlD|qcZi}Yn%MdNM3AB? z$tz@eMS5OGj;qX)(Bc_@loo4!;-{M%T7gVvlw`;`@sM~pt(=f3s7Uw1?+4i@W z?6@4`n&84ys_9*=8u^-GZOvz~Q&EaIZuM*Eh1HYlFo^7Djs#d_#33bS5+euu%Z`Px zKt7$Yr&b9+vcJsV6C|g2>~cEnN#frW+jx4$O}cKMYXfRhLQcS`xCq97iZLr7AKqem zr8-o)_Z*@1iqVXA>Uv}dkwmE)gj4}h7oY%O0qg~J)0VbAo-j*A(BV9P92CgSXI%5Nl?Ma8e2ihq6@465=f97uLRg8_ zm6bU?zh9WmANwmq@jUv?zK?k~hiA5Eg_(7Zc%|O5i6Bk;%wH$nb__cLIHx`!rB+Iu zr+a98ULzHSRhpvz0LbcWrnhCay-i45=?No?OOqr`3IdcI0xyZ(b^Dq^%dC>~%JY z^$!kQ=|<08iozs@31qihXrqeZ(JmMtFgmivT4xHXs6Jfho^$CcE;_kq z7ZYjsEjz~QC%0sdG=>ettV+O;t#R zL!Vs{)acrlxukf0)@w*#SMa1$TnKGoj5Y0xNY5Ydf`F4o`6?vkdwi#gFBxhob)`-6 z+UU6thCEf`I8qHx!d(+Zy4x(4(5l={WQtAvB!)DBa@+%w21iZ?UfD;f(&beFMpFT9`NdS}3<4X0~h54n99&JI80);^z3_3LHd!9GKY*ZX6B zNa5ksG_4EcrPuaMD>bCIM%wkvg+xpsEHTHRtsGyq^09R!o?8^%q^dnS z+Q?_c-vZe9iVZWs-Uqve`&@?R>s8g(S<5>sfUNg3s+2Fi{#9d~S5C*yxma5t40yXh zxEej~r)8+>S9U4=s1g#^_K`G&jAk>iO!otKA0S*7{w_>51D|bI zjoth+NviFWBV~r03owmmljM!$asx=)m}9kFdTqtIK86acV$W^75GqOMyyYLR@)=0?y+ z*6gPQ3@bEvIKVa0P2Ff~mSQJTo#nmHJMk{JD|ow4vbMR7Xd-vFmOHgD#~ha{6Zvqg zCOHI6mEFJP-JEw7%UVi`l}l=uE^C0btdR&PRsY4^99EZ!2+KFwuus9!?__P%;~ zk<1)D&CCfJ{{W}~iUci{1Kf(`mMSV9-dD1VXLWj>%ABJ568Pib{<&e`tJtjkMRllY zI!OCnhJ_*kpaYpQRkjLD>Z zoJ%tS1;nCrChK_#+Um;NlyH5ksin&8sNmdOZ`j+_?@isp>m~%A*G0VYbeI?n-fAzH zHwg&++)+D`$0Vt4iYlqAMAm6Z+~DK1*7c1G`$psUv+8qP&n(K07ZON`_hAnrM$tvI z6;sCt?;6rAUEKLPS;iWUVL4XidL^#geurnESWl{2_;*$jnYB+3-ASijmj(kRxQxUl zDEy76$ug^R%MSIPkx!}gn0m3V7*>s)yLLbS(d%Hpi$@l73+QycM&tcfo*sLzwZ>cT z{hl-|k~eLju!) zde#`ceOxS*Vzfx}a|}gXJlAhC4o`;qm8vs;Z!}hj8Kfa!Apqlm;Ah&MJoXc5Dti2l z=x5cw6y&ekOzC_t;H_sswYia%^*QC!lTy8s2ah)Kv6l(^*9EY#lEr#I6_#^W6L5{= z8_L$#SMnY^4__M}|*cRCFhNbx16r>1F!dz~{+wMq3&nwrORXtC@n%%HzJjmJ2A z4D_t@RaJ0KA)!D*~u=D_M}&x91~x{dYN@*b_DjM6puHO+R+M+-EXY-u@fyJlbi|1LjDR*vt^5%3}g3!m}|cxa|a- z*WK5{Mp03N<-EDR^Xp@W{n~vSDQVU^MdE4F>Dm{WtVar~2<`DS%@e%vOp+tU@vP}> zBDc%ARE|w`)LgexmWORhaEve1&G?1z$*1v6&BQ4#nAa$`atXsStAc#;kAl;LV!t?G z$2r?w*)>0`)8$U~JZx4iQff@(XYd}oarSs5)}f!zkcEm_E*qk=2^2c*kxH&XLVDMs zOD(%fHrL3;d5Vf{r=i(N;9XuX2DP@6;s&&{v${w%VQ_>Xg6S33b$HjzSi=_%y|JHK z@$*at8W^iiJkv_|J&dn2tBAucS#rU*q1Eg9PL&3cWuoi%7T0NQZY=D4Q*5jD*hD}9 z9o4ZiEyx>wK&4;g;vmX|-am&e!#uMnjUAN--w?=R zWkw@ANL+eW5XWI1OD3F+USEji=C`_Z+P{LYBG81^IwiD9(nBS^^m65-N0k%?y8A;s z+qdK7?0!h6-8ow9o5S7~drLNL2gEm4_Lm1UyV|UBmT`g-W>8BE<7p=z z_1KY&r)Oax&@`KEZrTqLTYqk8l3Tdbre}3jXt|O}Lc47WKJkrqsQG~5s)rd|==J$L zD`%(6d!uTO(?=hfKA!}$U2oZjZL@sRM%YpFGi=BiTIIxH>Camt+KW2qZPq)XCbxTV z_JOkZa+ZR^R574LmMQX}zhB)Fq=U%LE9PtA+%BM!{LJdm>}cu{X(Da9e3mBS<|SLL zDrQxJ@&_fyn5r0t&RRJFoF2p)%Pq!Lq`!Ei;$u!yg4FPj5cnHg(B5bxvA&+xP!oKx zsKI#y5H1zn41^vI@0j`?E9~j!bZV%@wBWjR6|SV>{rBA0@P~-CX#7=eb$x#A7<=a%mxsDIR7>;6*-Tx!Rb=IXwb_ zS+>rFZd>#``@p{wV$kkxbbSWc&vkuv{{UcuI2haNPm&SQqdTo+*r9nt8CBi#^If#& zo`~}Ccp8+W8j@b*_GT}Sya(eOT}tl$>c(j-?EIUn%k{_Ei_Qbi%Ffwu^oiu$6n+)Y ziHnkFwUXj!LNJ4ERCO=p)vfn#X?Qx@P`2>&T6$c~a~`t`-ORShCET{?lC`?UI!7cE zD#_F`HaNlH)Xq0bT~9i@O0`JBHj0<2t>K>)_;MS|%kTI|t+d@zLe|sUY7r2^D?PBp zqiY0G-d^TZW;~8~uP+~msWhUX+)o=BH!0ZcwEb(qcd|U%Yg+1Bh$iAivw`K9Nt_uO zQ65P0!|yP!9p(79?%Bm0i8ky*sB6io>2kw)ZzhFq`wX{wq>XAv8;ZpeGTcnr8+NV( zde@zHi&5lY2Y;mNslz#>{#7cQEQZ z*S9B55#@@x?O|~9gHwy;lG&6`!;cDE+1`Y)^X^*OK$jCU$tp2Jk13p;ji2t+Qme}J zJ24S;Zz_$-ec9}qOIzxm4YG&N5ev;SC3k?T>{*}+S~1G5GI7Q$(pG5jd!8%tA3*RX zk>HD66T|XJdUV_2bvCG{?GeXyBn=d4G~jtFB&?CfsF=raI@WHQ;z$VNh(N;(4IjLDtxNJvZHl(<2mgfSEGM%&4T5-zUaxh(`C5ug_gL1qOqRg z_gbq9jXX)Xxr}TqZRAuc1XFbfA^9SgA=L`%)_qS$_;c|x*4E=m(REPmcO=R7cJhRx z;t8cdx!lp8GB*#knVV<@uunCi%J(4nI{Js$yko0dlp0;`u*o!v&9nu7GkTG=g5pdT zCm8F;HRj`G9%!rCn&H;$^xbPfI+vYc98p|uw=E5Y@{t_Y#FmoT7%6Sbg=LXs`AHmN zvBO$P$KjXeYdudd)w~a@Xj)v2;Op1bw2gT@i_Iy5{is5!$^#%H&e+lI4!<}fA2>Lz zBQ+#LN+?FX%x65 z^u>46i>Q>PvGMqcjwHrY+))6od6Wg#@?qy~t z<(JObSp3`!X1VjcG=J#E7=d>jx2Ml_mOPw<^8nwTnDno9l?PEKyRX2i zS(md;GX7SV%)8+I3O^d&+)HmMw$g0vlHXIdQJd)_EX^EHpc_!I4yE#axvX(3>g(QK z^Lib1^LJUbOWliti}@O!BD2uEJ>hQ?X;z{;WYC@qn_H;Li;eR#&m1yHL3W*TQzto6 zr1P4>G~G$2^-@;1PxxcYsTfL>pw_+4r{T`Ip=iGkt7gXl3!c4p{LzFgtxbI-ddRVZMD1e*93-8&9-sE z9M*3L;fR$*C8}2ZKgjdpL9A1oS{+`Q@YCU+h;7^c5kC>#*<2ImTqF~TBqNXYmea0R zZ>Ul3O?olRE7QK0N1-e%Buk|DKS=O>{ngYG-cRBP)e!2MoT)Xu7ShN!9g*zEo)-#= zrbav`P1U5_@hjfaB*qF3%W^*wYnpzKrwMfgo#DGEky%O-OZ)!-BxM$M`Qw7!56mGP ze|(a0U675f2yNWya8#E(&U!zJ39Mh*=+kJ=YaH?_S_m#x-DV%^L&mDVyUz|e0Cpmq z!8mJjspb)zb~DWI+-GEZBYq7bLd|Nhap@ zL{6him#a9PetktrwAa$`_>Lr!RhM}X3sWZKj@~%S!#4bHWgYTK%@Le!%^s&8vT~F1 zIlG-s(#vdV5WkjK{KkP;6>*)}o>d<jrwj3qrcJ6{rfEY!R!VAsAKy*iDkA}jCR znJxoo=i9I{g)f}?6Y~!BGpD$;mPWOi z8YYS+G2xY10K16!kA7=R47%U7a#Z79N7sO8rORD%fcyujIS4E7a=h%nu;#7#`&9s1$ zpaY*TJAF3N%du`X?KoObPH*!%D=V!G-wgaN@NT6Xk9ns>r`gFJtQHSF;Wv^_0Dm*f zCt&+ddLDLT3(jlk=UPb8jvg{v=y!T2#M$(DZTvkpg>iRx2$|#-R}oyby_lKR5%&?j z;^8(1?bo$*Lb|r61zf&Oxgwv4{5PmxX|d`WmW^pFRz7^P!y}8i9vNlxcgYcmD@h9D zq^xm}H&;BdaGT{$$7FDmgi~n9T~cfGBHrTPPqk@I!*=q!P1)d0V2@+pOKJyuFNp+07e9RCZ_q{wE zMqzn7{_=nMFWhLM+)1yEwS~p6gl!$_j@JhftMr8>n$Ub}oVoApp+@U6!c@!Vkqc*+WZfAH}{{G8T z)~!~+T}@_qRqb#UU;V8 z!x|9N>>{|fmc|za=Ge;8Wrq9@x)UFF*1RlAqwOT8D?Vext0m0ec3al`Q1;Q4(sZTO zT~5ta;~`;=HCHljd^X~Yrzl72Yf5-;X%){tU**2#Dt=<#M4GLYhO}?4w68wYG&WEN zNg8PvcgzOYf0N}afxyn?>snBR<9c@IYpW7W=dScUEeME-oYGr=SeJkg}itm;(9 zG^9rwMBzzTuru=S?_P}w)pZiT!}lB0c4dDQ_}f>rvi{F-@#_~8M;3#mMWB zB>;8K)ja&TubahZl5duZ{{S=N^A0AjTS#cX6F*S!y{@t0`>jgq<+Qyn*-!i#e56Kj2GQgG}!(OIM8kk9{uFkgZ{XgKHxo%3MN>yt=dVS6_Qt;e*Plxw- zmux!4<3epT*yaBKk7Xadl53Ja;H#E!V zi1=ly>CnqFz)q{tvzNQ^pNMarXR(^v))ytL>}F6}Q~-eP;j%dA0~LilriD0KY06z% zGN+Kz<@dfLu<$0IbK+?3H6wo79;0O}aNa{;pqJPLkvqGct_e8+rbkTIrI%r&L*bO1 zW#6IgWtlQpwBMo9UIo){7JXXHZR3&4wcVLjvEJ?TNWw(hZrK^cg_oa|$4c$1O8)>3 z=S_MNr1jXcvq>^CLkRmRTtZu7ED#sl<}9frLcy~C0K8Goa2=cwIqFiKmoqb_?#XT~ zb=kF>YhMoByeE8jvf0GwA&APXtL6EH8BX2I`#*)VvpB3Us&b2q*)df3jvK^!9hZde zFT7!R0WMP3!bvrw68FOTI_nyA`hKf#cQxc} zuX&{A*cFu}j##A%!d3(T>~N~Uash0d@iX>uyDl(Inz~+%qul&EHrljsKA!{;zMhG4 z>oeTEVQtYsSXEyfI4sS)vH3-DRhv?}`T8AjvWrZYMVkH%K1+M+OIs*)8!N`q;uo_I}mvuC#q@?r8R3$B3jG zNN2T-p5=1b>}#(F4oZBdCV5#`#5qMV!>hIDQ)~u;LE16(C>s2OZGBl)8?1YL_cVcBu5#B zNBM>Vu;&%cN~5)&=T;(;R+M%s>RvWmOU-pA8}&=etJ7`+EON;pnXTbi{L&+wN3|7N z7HkjU6|^%aNjSRwb2~+2O50ttUmMRD{$^IrX})IaE;CuOAEaR#A^|P-qz+D__Zh@+^Y-_ z&HLv`=El`nqAaZ405}=qx$v0!IJ_gAJ|1R|&~TJ$QIsPmc_gk$us5R*3GPNdn7^<9NSAgq zw{N+xlBBAtl7C|Hx23f^eZ3WeNwx58=6bF5sJOMcNS&i=p%S!;+e)NPUm)O-!8OrN ztBd76Q!mH5YS!Ox$n&jM&q~*%)spEKP|zOwDXryHFy2Qs%s_e8PT&iO^9fypmH_SD z(zdAD)cf3?GWxQN*57$%DfB%S(@2>ubog{-)gb=>iPe}`Q6<{yR_Zw!q>27)5*Yi1 zuRAb=s$u6C>n9Vd9G9?aDD^mmb0RcsvPQrV>xNbYb|Zo-^SW`JC9aZ>-h9QSeNR5{ z)rW@k--$ZJdPTGr*7Ha-tNUwk0yDj*+P50yn&Pq$8}>VSwa5*YBIsP)K|gX-siyP+&Mb6J)|GKd)Us@wF|H9t6d_(O-DwX z#0EI8H`^Eyt<_i=7ws{t`GgNFGJOwfDc+hrE*Qb%sV5n(T37Wy|I&wDy|&aey=r;p zTMb4l32nqVkxjx``Hv0}g5;h~^?jiK00}(Tofqun($!z{6}fe>#oK+F<_Ip}B?(dF z&l41NU+(T7$njo9SxHT%w|g`7%9&ORF`&7l7aJ{CO*S?BA9|ObD%q*s&8S)Fa7n1O zg6v~EKvW`097;GxaU&Mb1E*TrI9SFU(Taq-{{X|EnP)jJ69rS2jpZxvbnWs-t;=IJ zw>`WXzlE`8B3R+LhC>vw#UR9r84P4bPu`5M`Fj#@IOQ0^F4b=DeRb6GV<#Poek<@b zjhxVZj@}DRHhJys46u2Pce3e(5~Do6W+EueFb`6v8C=%bd|PpPYiH2w!PIV|O`Q7a z_LkTFD!Ne3b0ilqLLHBl8(&__Zr)ms6MiGzj^Lj4*s4l#jsAae)}5t4BdGD8g!N?7 zt|7C#zQ2y;k|?yoizF+CR#j{aqDVnsq=hFI@yK(?OQ{MU#)i?9*2l74QYmT7^WCen+uhMjtqnqeLy(}v7~_gniV z$$=p--YEdXdKn*a`>K$|=Fc;+{ut2vkU6g>4U*KGw6^~4zwpP6Pb!kut5J#_;G?Ws zT0OkBtZ(fums7B|#BoaLYcaOEj{%HpCzQZre{c!SePvop;d*Ir@;;jg)mk==w%FUZ z(X^-~xA6yo^w+p9tao|m$&N%vi0`+Nyuma{Ayq;`{{RjL2E6|OtULQU^0)Qe3$lUroai39WQJ&KIi} zLQ&Z%6ueFFw@}jT6I!y=A-PLg(&}}E2vg_H8_ywDatu(q2@ykXBRMtmFviArgI2me zsYXeurf2G28_;hi@fp;2 zF6Aqpfu`y4*!W)3&s0l$S;dlD-icVvrQH=zEw@}orLArk7-#5lpPQ)JN|i@+?IdwH z$|~IsHup~Po{Vm+k{5(L@iV)I8_1)t z*!X(KM!UcAuXSG)B=Oq7_hNNu+1XR%i_93#^MrTF?f|Za(JnSPQ6{G}YpEr*#l^L- zStPr>Vpxn|Ge;{IlmYW_Fb7U6Kde!0M*5K9E~k0nZyC)Er1uuzWw5+}?UL5taZ9Dx z96Z*o`@9n2Lx~iF(4Li+HwR9lw2f&^rgtIiBD%G|h8XQNE2tp8T`Cw2+?%8UnIyMZ znc%~J%TUXc+akVxl`6Fpf=#6NI%`slmEMJkz9icq`!=^=G>BP9yBe8fjp8^A(Xow@ zhqGhTt#ee#s#Df2-18kIm}=T)n$~uUq-wTy`Ze>n?&fH2ZJI$DWH$b4&9lDXjK43X zZGy~e!8K7kt%4OCOdl3Dwc+bHq(#$>t@J4i>NYlZ5nKtKh?qoMY4X-Tn|h-VGrGMR zIghl9QC63k)k>qA)aPWt4PZ5K8dY=J?FYt|l>z<#@qpyB?wOUtZI!`~j&-rVF;dj9OYD*)lw{oFilARtN!; zpYGLGtIHPN$j=3am3pzK9pulP^a}_gy^(BZmd@q~B$!KV;u(CjQd@Heh>?I!In8)9 z>(r9JL-eeE2Mb9;pCnwg_1FFh6_TzkL>|sH0cytiQIWoT-+#jFC%Vc{odwm za!xk$Ud9U@B?xmn?tD&rms5r&Y6(Rvenj2`{?xtkZHs)?!6Ip{S}9~kk`Mxz$wH6I z$fur_)r-uO>9m%;&l?Gae$vll*=_XO2+4Tu<4Kz&+!fs`6Ui+rW=20#UMs07J2rc9 zrxnoQN5s&Yy!LlGe3rKM^RzcIvzD4A1c35egxm*nf_Uee)7Yr%a}TY1*0zUPb*~`M z<<&IS656VtFH<0!VE7~i{wd@b;yA(o0BESqZ$^#vkn7^0m6O!j@E3u67Z!nYscO1y zo2)H|ySa@97TO5oxOZk4+HMk7IpVv~;=RhB5671D?(-1X!6l?F zvOJNNK*+#4DJ0(KoOp-FULWy0J?^b>a}J=}No#l^gk^F@&n;Yz zSm!KDcP9eAp9w<;7;?*;@Fi0gr|zgY`kue=4_ENT?uk0-wz94Lt-+4+b}ak6;gpx= zXJryBUp9M;Wbt1aoY9nOrr*2vPk#p}wRiCzpKzB)QG~~L<-*JJTa*kNVFa*#tHHti zF^cn3(^I-vxxsvYxwO;19^c-JWs>gU?d;N1k+eL^CgMjwFPF!Dde?qYcUsrzbK@1E zba3Ac{xK`*G1_>;#F5P<^zvCWcM%1a-Xjq5?jBvfT!`!nzWzrCJ!`iag_pH_ko!B| zOW$i4QLk+o)_CJk(rt8^CU~W}vb>ESOcTi*(%fD~K(uI~xbr6aGAlE0AZMp4YqtqX zq@CxZ6+>n0{2E3<*RlWH=4v1CdR!HxD9eB@H@kIKSo~@@^+uzx2o?9~{ zV%}zv$OI$hl24of;mA3`>IHJ+A?(uSZR&4Iqi<8MywNNd7kWH0tcwJX6{JWM7m0+4 zvPM#gnQ^qMDJz|%jw=dy$+Xn1YnnLrFtpzfcoR~xwvu&??_h>BybUy#(+LtUDo;KT z=v9tNw&BfveHc@e6|H0QJZ58#qgrwIlIGJxpYghAn!b|L4Z zVF@Av<#HLzzCr?6@_SbvV^v0D*MGRg@D7ov=(iv6mFY1s zxK-O{X3RHULC2i4Gvuy9;xI_sKsEE#F}kW#d+z%mWsjB}RQ~{Hk1aL$p7{PEuw63W zSrWJQRmHKnL*=n;f^hU8qM&*5hckCNzk~Wk)sKs=p@KX4VQUC(uG8%wG;Svg zZyPe0)rLI7gV&!*bCIwivmR+A(zTKgmOmE z0NKw64bK!wMvW`SXus6Q4@;NbIzJJ74ZqWp8_hGs63)*e!fmc#W{if(1enaMF}M4* zge%giqgFa6PEpksd@=Cz#GW12pz#K&bqne?ityOkTBN2n^U=e3l5JeZs*NM6hCe9j z-%5Ov_aF_sU6$Kdw#$&f~hEaRx#&PnAe6N+ej&fuC_8cr&si+ZMG zc!N)|@ZPm-v0gKsK4B#P0AzyN+{I;bJd3=z1v*7 zrg(QnTZpxtTUfWhx3J6UklNkuwBNa|76~1ORf`UaxL~`RlUx-sRV3UZw10=7+Dgsn zbDt3WJK~#|r}0INvq@vAm^Z9%9m!R|35|$^1$OfHZOGa=?@ER$lb5qkSe&uNrrJ1< z?L99|WxDfiE++t!Z!#?7%w@r5h~_t8&@sb%n(yUrLwd>$Zgx68sbQ^J+FWSz!>8)+ zx;wa84S-miBF9Q@YeI4y&wc zR^}NjqjxRM>>%5tfXHyF*jRV%8RVMQoMNLGrDUJzZ3r~hhk1G63maWB8>>{cva)DH z>lT`xPub)|+OHSPB?Z`RQNOrh=~zymw0BZ#)2cm19$4(G_qobwpBB6@EMS9FnrN== z)JH6yTS%@@V{m28bM7m^#qjlSXx%F~y?Y-SjKIm%ZW|pJg8WUR_>v7*!9l4NP z=$G=LK@IOSn1DEMyp1CIjq6_33RP)RUeSBoKDu{4hb)wxB~Dw8)Oi3?D_hen zbqQA5G_u(n-6%eM6DVAWp(DwLN5Z+d`HnHPE;!y*oLe^fwf8kNn=LZi;-06aMHr6C zO*}%0l7Ho#6Eg-UaVO?tNy+P2%2Ilsgs9q*f8KwRG^hB1;n|^?ZS^aSVjEa~*w*%N z6qH1tb>^7)U@q?C8Kk4i?)16m%M%r)+ZV)};FC|kg556lg}k~bS+i4Fy1LSQJ%4v7k5JLgl&x*6Y3LdqzFTY;5F<9h zpW=@x>$be=`5TQ@I&!+^ySZN5PctJ#)30uPAANHKd);TVSnZkAOCo98OQu1Xs81+#fG4+8>-_GZw1L_jlFmQq{Z}@SDQ=W#z`Ds|{mXEB=ZuCKAXT z5LXdGe=_`HwuMQ{rHI4gtJIpbd12Jp@f3O_T7I2$_B%DZWb(BQLADfFA(mTYk8`+J z3cv+F-Ns1iSyT3!yXnySny#CSQ{9@M3_c_4x|Xvaf^Mx7?2BPB(sgv)9if9Up<(x1 zW;SJet$3NHTL>jxFM8_e^D9$JW1`e_?-g6LI(*LnvbcaLw~qtNxwl7}dx>9$Ddoq# z#^BBJsP1d42}+GwUwQsW-5f=qjIM63?e&Jamj2()ifh|>Co);53RFw1Wan;B?g#@0h{ z=$m9#0YQj`$m0X8X+oofwor_E$?j=VqFc3dlCy`z7LZ=}i(0vo4OaUG?^0zF>J8?w zQ4O?ljgV*Mjd8uPzzQp#u5lWb6*>!^Z{&_Qn>6`ou4<33VVAo7&xdVRW8v$Vl2$B+ z>PS-N;m$HlW#pbmZQaIeo~}WNs`;waS7!xGuC-b7PG0eqXYm|rJ|MG$TCs7WOTIZY zh=a86a*MhzIAD3I#A9bp?Vgp{g~?$-U3=9#v)Ie>sx(w*CaOu_PN?-O3x5%6mkFp} zsnezi-)8>+R$AR$0kYK?Fpai-`J`RvqN)n&`mZ*RSoJ;XcuCfm?>*RbC9=8j{0%kT zg2vh=g$2R9nj$1wZsb)muKs+-NY@O_l1t*MwfR(5heRDDn~L{haF1(erRg^p_t7o1 z7tkQO47R>cn%J@nMX_V=F8^AAPUX_>5L(R=nj3UgSEm&xdUO zAhwHlab*Phe}%OabcV*#2=8Jj>$T<(%H@`wwXfl_R^8x61an z-p=T(MLJ8D-}N~QyA3N!5oxw-2Bi(y4|ij66zT`r_XyqJ%=3hbWj`X2G53Xi20==$ zKC6!}CYQbMe?u?r8Nx18fp5SbB=ByLWiExPTxvRgsXX%;H3%n>ZIf(3+soy|-!t$R zYb$ftt#oEMS4O;`tm6~f%dt_ERqmxDQcZuvzAw|^lIu}6np~lhTU$&=yo{rQ2JSLH zjhp?^UptP>eT2DEyF3izJ*iG^7T2-VcoqSscxuh9^Y(iQ?&G)Lx>QKb!-+69Z3k#C zz;oYdRVKYUP1T^J)~z0f3lQ8>dR-kxhdk`}^4jXbEgEP9mp0y5mPtflf^G{)PE3Jt z+2{brO7UxEHDhQ(A0yF8OIBiA+QX;CV(_>PcI^ub$y#~jRwW3M-ZfcJmsMPb$nTL| zsxyPG150^!NKDl8IDDF`6YwK2}njjB3x$52aNM zb8~v#3RIUvmGLiv^iK@w2T;*8<1Eq3EZ6hKWp6V}ibxTqi6$lX?{XJ^U8Lu2cTP%r zHYmp0j@G^I zF%fpq?yMGFW5bDJvMtYvv<;Wm5|9<#oy5hol2bT)XHs~=o||aD?=JS1=VdmeywTA3 zTJpnL@mGiDK(kuhT3kmy-bW258A&O>bn=^IRTtg@BMoWLXYp$DiyWO5{CRA@~N?g8smi$|w z=@9FBuAG*^bT16s+Qn;NyM%EIn2SBn$s}ykGq3@^W+#rk)U6u}^3zgVw(fbg*Nt@* zve!Sf)=BjpTH47hbs|d4W3~p|9jEVaK+0Pq=Id9?%q1kI^gC-k9$y1Wk$-F3*jvG( z!++upKKZxU{js*jV;e&<$v4gZtxr$7%UIT=rJ=MdIC>m*sqv@7#%~U`hvD|O(lk4! zzPN%r8t<0l*eT$ro_t436utmdtAM_EeED_c|1Z9iy#h7(#W@?Kq9 zN(aqtExe5&J-{)CL;2U|H8?vR7i6O)>U2XN3u<}(z2glpTk#X?%4fIJCz>B384*>k zZ4k#Ct%*KH-Xm|5a3a4=$nwcy@DZaY@7=vSv&^fAQmb@UmiNROu8!K>?aSTSSzO0& zdwD#IFv*z98%2Zi>@x&*{^{@A(8E(y>Z|lQF8cp)5`8M~lEVnG` zkr6R4y2stlB+f@1SD}un&rPI{GZjOgl%wQ&-;1@!@c#gZuJuKW?GoGUSfeKjWs!tw zyW1_EE9U99dp%E>z~KI|S~Rx1vE|oZBG+{#k~__AK)D`uq-hWQUZOBSI9rFjL#%aRL*g;{pUfb81J#~X2s za4W8zSyYYMvqm|FUrP%$8go;N`_bL&-UqX|)GUq4jYCViy|jY%-gb~pByBRrsLY4` zAYuMrG;dzd+LjKtGuLy?#8XxyZ-V{^l1~#w;mvzr(*FSAAM*s(YcWe?onv_w5ts&X zwN<+P)*SO*gQE#OQu~i7)49t0Go3W8Js0e=iLSMHuOign4vihKj9vNiADI?7cu_LVno;!z-%`xMJK3 zG?6NnjAH@L33Uxugu)6(%yyQfFtS@fvy66aUDh`|k{MQ){yC6p|g zU<8)IQ||`(PeILiRVT|S$@{5(K850I#uS=wp}@i5d(C@Szq-(6Xf5Dfx6q*qvs}m- z)nQYBNl4hf-hDZ&u=V+AuW!FkBcC9~V_`;06O>ag#T+_ZQCR8lE|cOL3z#E}p$1rH zmDNm}y2_^PNFKOUX&UXD!$?+GmpXwQ}3YaCowcQW{6S@APFUTN2NrL^rrOW&{~ z$8B`dd3P2OhTS90<`~oi!vb;5d*4@zi;C=PI@`YIWv2XA(e>#r?zHVs>~dN{WnC`u zBMAOT4>G)qz4x|CrD8Lo14lQ~0_wI6+D$2c+tkI?slmOqWa-Np|gdJ=AK~ zGou8GLvqn&jI#OjN4zIREncK3K4m4)>Z^*S3VzOh>}2hKGqBPxqSG;$q`&N#MsD9F8-J`c4d^C}REAnsL^Oz;p2Nf!O_z5GW@TIP~d8*#Qrrt$p&0!y!(nIGH7@hYj z0zlo6yqwpI#`32cl-!lojdBSkPEY&ap`mU(RU|i-x;B{atgLyuhEWZcpFOVdif(P@ zKfCi+at2&6+k!jS%~HX0wP)`BE9QMQD$Sj!U`NXarR$96Hvz^_(VTgKPuQm)UTt#!F?w9_SqoMi>%x4O6UBSwaJL=Du#N4`nMhdP;XiTi*#gS&KV#it5P$^0fPd<+Ln73~jDeT*bd1GBUJh z&xg(i|rFha$wh!He3_{3XW*0fwSJSO1LfS2glzD zrLL)SY|{jeA)m8B`1e8?V4Mq z?ft~)+KuJbP{^Y@h}pl9mLrq%5>9J^z9nKRe(^O;Y>~}ctDLS@)@)|+2Ct=Q+J(F^ z%M6i4b0Yrt3w~vfVl$}V+uO`rBdK3X`b>s`ijKJ2*nP5>LmI{DQT7AdqUY23}C+2-$3RCCCr+acM`t&@O#%UK&ytzif^8Ux1 ze*r`0FXO(vS-D1>V7F)JG^oP1BCSbn2Na)fUwQr~MdAMd40xMVwzz9uGAXo;MkS6` zypf@bLmZ1Fa-fZs*v3?aaq4-mYXO(fm)<`z<8CUzLb`+{c`u2rZ~p)cY^J93t=o)L;k%-&5e#DZ-q-TI+=i0b=DN|`mQMvC|%%GN=o_XSkY;CkJ z4QlYG*`&SmX1In%mw0)$$MUq>{{VJ&?kZTHyMjQelw7%@f>v=-?sVS{Z7n76E!EVq zA|>voEbJvlRmp@MZ-^R+j8=jHput#Ycf`qU}kM6S;^QoPzboksRG@TY?GM^e&w zhW6F2;~3`Iru$XHN$9NZihXxtzJQ^gB)X34$5*Mg=3PeBZ6LI^w|^`c!Zh+paL46X zT+UaY?wkT^#LXoqB(zJpGJ~Fo;QUG9%iDEH?R4uKgs`)o^7}_nL@Nx8s;nlM7ipa% zeX96XRlowdy_>5C6)8pZerDD1bDcdMta;=Q@UK)$-AV0jY}IYh+gZ&hftqFB&y8zu}tj zAi0;B?Kx_29~tj$^*;c3g4W6zbwG%Oyh?nFd7zYFth;u|<+v!U$Ag?;*Rz#jW~a{d zM;0=wwT~9M@Lz$n%>zr+8t&^>)Mwt)Y4-6l$uvxSz44@r`?ZPkg_}E@r=@!^uQ^Gp zTE;S^O+`xgXR7Ny9-1G7+I7#_MTGVbYj-m=TO~1hhS_1AUlMt%4B0$w1bm=ZpN6mg z(&No>)uyFSLs#JIYf@e7R+?gy*T?R=OOq@yWC*;yVY9$0)nA}*yzUlAv5 zIw!g0fAE89b{-Hqw7RNZ`Dy0O1==O3co{=0!y_?QY#veYPw@Nsu*Q4NEogn*u=-sb z6I#QoYSYg4w>pL6Llzc$gKrpsGRDs%$TyS$mOSnoM?I>lw3oWHCJXO6YrFkTZhXxe zTf19$Cw;q|O3_)AQ1M7$+><_-4n!j z*N+aF74EMVr#iGy*;-sH#>f|}Q(Og1ZOI77E6xXc^Wvc;beG(4W;u3sgssUASySmI ztc(vF>Cj$5r)u}NO)a8H_8Wt#N9WvInIypvAwFX)aw`I?$8LU8irK$)rT84V9(h_A zsnNt!gyy=nbar13^hNOIu`G6%yBhw;%QWk5qBTo7QJZXQfCrT;eC)>u9CoiNIG=A7 zb@0l^)>p(za=THEpJiC*;_%k9tzE-&Wv<>@-uRYfn(EE~f)HjKnG4hJ) z!aL2*YR0m5jgJ$BT(@!vu~*{*mVOGmUxak+b5DUF3e$zQki~YPUHY-OpV3 zQ9hsIO%Ws-G!pCjRnnWCYVD*jER)N+30f%Ie6klmaa1THB&~4b=}A2wyV)JoDnii=8j%x`bw!e`+&!<|)pC$wWO53Dm zw#bs~+DRL{!mW{9@x-ZL$nVTDSz#dwb8FRhMJ;x9)$T4ewzh@~>)4pxUE9eyGATeX zvB=Dj?o|Qy$8r1^PzuBTKfT^!sRF0G^3X_iw-wrjYg zzrMEendG&P%rLYr0Dr%<61W2=2c>m;NYuMs4e3jlN3p2_s#>kJypanFm1%du7-uRN zBSwIRljh)gYWq)htlPJ#)ag^dGuYM8G-$2$YkgYqU1_>A+e-rKOC!TJWeTTx+qomy z*!gfqbASzHiLW@p`#U-IF?FKlriS;0?zNdO?xpbkq}raZ<^7*k)@Oe{2_JIEqBPwE zD4{~*d+!{Lyk@(p!kp>etK{-qkgL?asl%Q3Z$k&hz8%uFd+D`3TTg8(S+$WP@dPmZ ziuTjtBGe&G&z6nZM2oqDWOL1JN(pHlVbPgXyZDu-)fnFhCR;6EUDIWe4AK3PSR8VV zEuNtohEjVllY{7Mj~f?wwcW414-V};Iv$_l?-5&S6JF_ecH-sbntRKagpI#ty@h=L z0GEFEDD8{@PTU&CtXyo*PK8c(;rI5nOkx`Iuu&todfo-UN2?xh)NFD}e#$*CPd^*HVXcfNSKQyLwr%kqf8+|A_d z0XApu@tWiM_rJ4f`f21zVf~LX?|<)qko&E6El0)?%Pobuv}+@0{hV$>T0w0B{^&cn z3&e!7tc#9)vt81sIi%K!G|!98aB#!MF>WraZv49>b=un9+Gsiq_w2FUDxhO*{%m-* zvvfsSzC*faehT)^4|=>G$1hXQ#ye9+T(VxpVrJ9tKFMYV)UiZOt{whRyRj#g^JFu1 z>$G&QO!Ct+H4RGU4K{e9b7gNk#`?XCd@RA(nB?+L3dq23D}`aVJwU5Y!ffZYFBDqo zSL>qcaoxqGykuSl5lQxh4nE5%jfo2?A`~vTZY#>35~MkuCbf50>D=`xV<9Uk-qzOL zdlTt@1&*iTojYH**5!uJQ)oc5@_AphT!=V6UxsO`pshQMqm9(^P_o2%T6+_xR z*i#bA z7msvnn`ahUK8U4J^#>EpCA`w93a>13Mj|^{t9gnPflQF8+{Loq^GzzzNeJYuk?mMdJO)Y;~^Y3!i5)MTD@JEAM*t2kDTvd07g^f=9ZGoq%oJLOlBS{pi# zitjBg3ba;Mv1z6$?ajXC^4=+}@cRpJt>%^B^MlQJ4X;o z@A5TuUmKloPnqU%6cJ%tO0#EqZkdP6xrWzdeEr2i=+zkN)zsA*YRX?|^|M^d6HgerF}7u88B@`A<2Al32;41A`}Vcp z<`w5zVZDqueMx+8X@4%8r%$L#+HSXZasL1kogW~yHfoM0xVi%XJFf~qho@ZO=8$lrX}Q z$@3Aovo_Su@CRdE+%<)(m(`n;zAHvH`(19lkBiM})1@zGRxh9VP8UkhCB4wErN ztJul4ju^yB3SrR3y|=mn^d9x=<8x-Q3tx3TPm{!B-74|rdM0eho)Xe6wAp+)s65_a zQL5?E63%33MZuW~RaJG2oys_14nASd_{g>R2q)vOuo)Qn#NZk!^FpAI0+j0JEIewS|L?D6Y{*Jt#QEU$P&lO{hob zOJgW4a}0MkaN;y?J$RVOhK-Y8+AtCK5%XuQWr)K?w=})$9@ zcu$;=EM=NcB}y`~{KshqJ_iQAQQ_)1%bmElE&Ps$ElhoTU!88Pq=smuIAaa$kjWCm zBV*0ARbeF3wi!nVxPCBt4^o~6l?1(;Zu_BgT&Hy_ppy$%~WkpO`dI|`0GH_ZX|=mw{k~fBKth>&W;{yY=kSi zFFSPG8JrTMFM?R{UgV`^ zF-_R?>rDx0kDhP!onOVSx7Sy5>+;*9BgqpqtiNgjV^J2=hTkLt0)oVj^%9y+*A7`d zj_XcMf8w5%d3iR9E%j|O-aBbEYkB6jivCz;1+689R8UHwW4m|C*d6c*E3GvuH6;{T zlTEm{)Zo6?v>^_WWgFVt=xQKK%d>fiRv43Z;}k=44s(&gCz?`rSG9?6n^F%4*l5vd z(#fS+S&tb?S>DrBazI8rL2oDTGZ>2tzCGXVSDjvRb4#amdU$sZUh+K4#2*hYwXYD# z4ws_Gq};{lo0|ykOwks%E*dxv8);^V!u+9Ywv3gUz4=czwC>%AygBgmMUu)76HhnW zGVfZPpN@-;F)2tvXb8ZNfKMDs7u`< zT#*I4Ll_CXWNl}Y=E>+du5WIgSw`9Nv`DuX6Oa)7NR-V;#1&EzgobBahW7uw86IIZpVipmqTbC!G7<@NA zje}8zjp|%@uYjTB9bzpz;a;PuOD4N~rAKKD(!CI}n%nsZMPD$ykDt27IeSVHVJwi#58xk%k8 z{LOuSWz?>$rM_vrKYA7I;klY9uPkI)O8ll(ZMoinp?#eGRmE0=Z974cuC67zhS)8?b6BRJ6r$?B>Nmj93q2)53P0kc;4S=%5dlCZ)v(s=8)bW zzt=oWkyu!nUdK*?&NxQn8$j4G{H`)`%-P+Jz3a=xV`V$jP`}I}%@%6uHr8q4y<1t+ zY-5tc?8vuQwk&}S!^&OU!pw}aJZ3*LVx7#G@z7?r$|s zUTYa;k|l=G1S&kd{IeNjRGoH~!ztu-KY{Oho+TwtiljF;^Px!9TLYf`NUxX8u`;Jt@mIO@>M>DH8pP@Bq_#)}y^YLw zk=i1oAeYUVRd_7S3$roDL)6!UQ<_rdlCu(p<#u@t42=fzV^J)OwX?BkBs)!H(< zUPbd|ER0oyIbEXw||-0{e=2m?wf9oZe`S9x;IRu zL-uP(l!Zn({pS7(o_=ifuFqjCR&N@y_#+z_xcdwfQd+$}Z0URs+TG8H??#69=vvZ0 zGE0E$RXoQBU|fUy!mZDxdHiz-DN|JwcU=tf75k|t{Kqll?*r?;CA-!9QDx$5Mezoj z9t-^lzu2ZrOH8PB%jAhRmsMfNBb?U`4k{Fqj>pl$Iuv2}{o_p<(&tX`UXHgOEVZ34d~o~d(hYh&lx>-VqreX@s+Ygmz8 zrJu_rrxBMCzaX(*xUUAI_AqrFoFlKP+^a@QMnS0fTSu@m=^h@??S(qYQwML;SN(pxNZlB19O>{?;>iS*1<+0P+Gi!Th@>m;r zzITq_%Xf|yEHJW%k7CHH)GKshUtfijr#^J=PD`5pW_2UXtX=T8gf;6;Cr#8eDWSXZ z28P#A>Xr(J&W;<5FP8BqnI!OxD+XLL@-fFA%qxAR)Wt%?I=_tkK|RQV6|=ayiy-P& z&n$7{!2Ct03)~Cyk7ER%d<#C$EZc*{^rG2Zr=*UOO9@-G1L5qXZh1MkiSA zcOuCR(25+wvaZ7D${AP&Q_W5$Hc@>U!Go)L)Tj2T&ByK?tLpOIYNEjw+eg#9MLD;5 zCC$w6{gD>hD|zkHf=k9sXE+4+BDbeYmI~%`#45FC8+->#sCbU=OwjGFFRyLy;j@im zk5P)@;=Paov*kjpsUwUBjf*Qc-V2=9pI0tU_Ug?X(^iqbtk+r{lIgmI(rHlwjd`ZV zps2wNw{RRw3167D++*0{ydPre)NQ2SX?}-2Oe0#YQLpgc2GsS(x|ZbL#cJ~1eW|vC zDa+~hMC<{6SncMM>n3aIa8%T3tu1p^8zY|aRrZ16PaL)Oppf2a8e4y5M-9NtXdTF! z;|vDf)0mYXy5_FBydRO-f|o4rdA+`er(AgYtyM5%ppjS_{piHs5|$BS2Yhne2M#)2YyQa64lOb)WxluXTJu_Z*aW>(h=u^VF zX-Z2*Quv8>u=qp7pJZg{*$Vz}cY31#ENI~swNW@91GPeB> z8?w;69sQ+cC9T5Whq#GFq_dz`4&in-R37=~)0+EiMiUDdb5ot)W8^T{j6q~8_Sltyk9a4t2@zP%4ZGnAE%YsVfl z)-3g7r$;rv+4Pb2Z?we%eV*EPMZ;QJWXB(r&$Xmt@1B^(E252WZ6(d3dZqqnOtQ+J z!PZ|2Ji_C|-ZPIxwbE|&B3DYfl6dX`ktE%fF|fH)iO%^{E2+6+Zoe0#F zF1{3ccY`%;L&qKz*Yr!Y^E^!iB1;Rar^J)MCS8jwkC%G9I}78Hf@{gI7~$(Fts&It zrAkhoziDW4R~nuEk9{=jB>Fa?Z@S*-l4B%9PUzb^p_dupeAV={szz~Aj>m_H!K#VE zdc^fDBgP&x(fk&=i|N{2*X*uix%*DZk5)uz)gCW5Zb=B^o;WqZQ!-Mh;?pJ^Jqi^0 zsdB7Xl|YI*6EcHu1_h;@-li>bB&)jbDuQK zr-zIw)3a|*X+1t>--SFG;rnEVQrC2%JRx`GwY~oU+J~70yp8v10YI^wY-VqnABH&T zva$v9ls!r@_#%rShGr7v;b{{YKw$D<_*anT+vdGMp+ZKZ{du|34FL=fJ+ zmYuLkr}=HY6qy-VlvDgWv5Xq~dKu0dbCoD-HQ((Ww6RmG1sp|5Mw;5n_VqcR5o`9k z?as@@g8KIT;U`cLNU}acNAjrK61#;g@*w$-YV|2ooFUB9j)yKjjv6%|vYcvPs?q$- zokI5a!Z%lu=~kC_me=q_X{p~Ad9Gu%b0+xXVyq!DY#%n>i;nflgOaaJ$=Pb`VNtjn zYw-g@(yrjY)Aegry0Hw441t|lSpt-G05{zoSEX>_aJ8d0`E--q)7!$^olAJb!2U1r zZl!i@FSI>FO}Bfuw}L;j%Otvzm@^3rwsg6FlPtOK$6E9~l;JOX;V0TDMcDIW;mdyw zcupM~d5>1sa5XE4@L3^M{o=3tBXB|WCb!8b{{U&@lV8Gz^>dFISz)NTeWqeX;Xe*r z{Qg@@8jZ|mbB;Rn3Nc@%!y>}dirRY_q3oQ|bDxz15f6^qoKv8c6{|8%6h;HwQ7WV~ne*?TX5^ z7)^V~aH%-G4zkn6vg$VXI%kL*%ea!-^=vgz*@oezQ1Qhs4%pj#K~*>hE4Kt!BEqOY zb7Q(S?$!4h<4YZDTD{WZuz@aMiq?DS7tL70x!D@AED!L>fCX^Mk2G4_Q|Pc*_|dAW zIP+U$&UN#5rfREWt6Pg3`)FjD3e60`LoO6=iH;aB&ep-Gh6&P+j`wGyTREYPm8Q8R z6*sH??%#RZX}Sfbwc=PT{M)MyBU4!BFDc{DTX@S>>i8(RKG{{V}=ANXqD;w_A(%6&@HQiFB&jRDM1wW=&o zT}_rj<&|BV82rpKGlDCdhcgPbuFB<|6BQ1J)+B2wyFgi(E^ zA+xp@D$F7h+&t|Sn}*x-w~(wKYV=jE{7w~Dj8pz^z~jeIQ<6)egLf5$!)bRq2imml zQsIi;>4N4^$t0)G0wT=Oq;~QntA>bx7=R0m2CWFs+S*BM%;~p#8ydv+aV!F8Vogrz zo=LAP+DkY4L~0^wQdAqTJlr^D&cmD#2(BCyc0dde6f4y0_Z(%{|H% z@~-bLcS|I3x|0Rpn;#LF-5TC~p+`f3gIxJuEz=`KIkNhQ$wtdcx^aYCashwvq3mx}Njx zFoP=11io2G0Lgp>ku#j|LG{P4h+fv5YOS7!t(RA|;$i$*H&$le@WYXDr$`zi!Mxq9 z=4e^RTqNpO(1Gb*u2W0eQ>hj4M^tfU^=D3{IW_LL%Fau}c6QNt^TU@DqRk(PG~0+S zk%H}z$G$9(3C=_+7?3jD``4G6zunEp?7a%6+OzJDO~2B#%^=%qmR7J?+gdZjcPw!# z`BwKsWRs1ftUq|?_;**%<#@?dn~QgB@1)cuozFMa*{^l>o5MD8Uqf`p8<<4$PR}fD z<;5Vlp9o#T?b?jX_eOac`Wm=3RtuTxdU;lJJQY{Ux#2C*koVEYsM}smCj`H<4Q4iN0C;mX+@fs0WEavJBw)2Wxb0Db+axn z;RPg*Zqu=m5OcKi+*YX=l(mV1-`^~#@I!H8R^c5)dAmq_xm-obk94rB4tdADQ7sYw z0KyZaUFs<=xjo(0vfD*1%%(JQv)stSCX^6W@$&^%UjG16I5C)sQ%jc3`H^>Hu&|EH zLGWgk1hap{s?S(dwUDkD!5#CM{zT6wX8?Owm55HKKAN~5#Y?Oya>n-BEk8$=X%%f@ z*QPgD48S5P&vI3rvxOVVh0u@8k*4a2t044YFBdHY7KQVo5CZ5gd88l5hl*m5EY0 zgQ(cvU?c;$dRGM~T1_=+%klpJFOlo!StKda_Vk}UIPSMCcyr=^fGs{A>o%LG{{V!R z>cUlM?qWERT})A1Tfa{(Atwuk9Y__;m}R)y_}X)AdkDV!dY>B!Q&DLvT*>i@YE~Ln zh2rKCY8KL3F%hXN4YkYd5uw|LO{8{2Hfc!b) zY3*RvZ}V@U+D{s_)xs>QsN>5rq;7s;5p~OPv}Xr3>rJNYdWxL+dD1&cP|jHUzISSdf--&q@t{haa9zj?wP&~hUBiHeI%2vn_&YP ze5WJ#(j%Bg-1Gjen;r3v^ruQP-4%q#)}ZfBPA6lfSbu3eHd6f7@dUZlo3qZ!GKY+O zq-;@+0=IhkTvcCWoY%zkkCc1=0A5GWX4#EOl_!X({{VR}$m|kWgZ+{%(_P58irN+5 zDeN$-)9cc_dN@k8UE+_L!QtxS9qGl%`IfYwgkjp=>spxGY4*61YfankS!3LDCB%DH zF|~@39)3_hYWrF+sTJ?E+w6Xgg39Ws^VN2JQBO+vv;P1He}-**J7=ZF+Jtd=&hW5e zsc=m3te#*y8CF%=nQxb_E4@@n9FGd+FYcXJg}x+do-LKEQFSw{LX%B#WpgA^TgVV@ zj&Uq*iwaw|2Gk+B&p4}$?h=Zo$*w1g-s%U_;F>*fT9_i8H{9v>>mCimgaRjDE%1EM zImbJPHN%a;LcDDwWj1qK-KCV~Z4T=C8{J9}WL-kkOK~mL&K1@-jAmI?1dJXv0XCfc zxUNTr_A^aAKO<;raax|as@z!E*hLNQ%jtv?>GJIs^ZepS{F3__pU*+KoCCrQssOJ~ z0a`R`siS-zWh1a{t4?Z?_6Xiz|tD~E0P`FBJDdbNDd z66Ta~G~*guN1IdE$*^@O$@A|k8(ufLvQLRismZ7=oh_u!8u}>Av%p}rgY4&NJ6L(n zeoz6yIXE@*(WvRs_f_TC^zn`JyB)rh@#bA7(kp##6R5=tBy#HUF!Q7nNgJf|TdLv} z@+RSPoytc+n(3iinS092!jVJC>efeP2YSgYkUMq&1q=o; z+PrF*YV|6qDd@gO1n_f=uYC@GRM4)pDPi#izN>3*dXbC6r(8`ViGv_V*!LSAK2F~$ z-H#^(8uaj(%TJZXyY;b*Dm&PUEq_3`xxY<2PP(;=R8RvMwBE2dU<Oi-5YjV0RrK?4KFYj&E?qx&&01~U)k1`fw zzch~%b-)?ty>?QBTE9>D2j~WBV!T+ z7&v6=ITfZJi;S<(+O+QzbK-rhT9?GX2;Y(TwBI5<)1CuTo3ow2-p45UZkoh zQJuHg^C;2huN3yZ&Fx{-KAWC@)8PDaul_aSLg&y_O2;YTjV24tCP|f=+U;(xP+dYs z=0=dV$rOf;ROjxxk=Gc_Ra%W$#+tlJ7e;>%#i)W|NY(9@TN`*h%PWz0x-fps2bpf? zXU-!mr>@gl#b073tY%$mJ{WNvUu%lk+y3_3M!mT)1l%^cvc8GS#=L#Pc8=WuxeOzLzf{2y}!HW1s3d&mP$kX$kQQE3k8CQE?KW!!o5BanhCpPq5sPeWyCZh!yP z^ot1e{Z7u_+1lPotx#-_eq_rA4z32)3+fc}$Tjhm>Q%#4l$XONsp-;6QA@E)#6C2) z@azKTS4ks|GE`bP4(}#Fh+E7)R`2(R1F2kBMH~Xgw4=NGOZ6gkV@+y!e~Elocc@-o zUR_vQyK1sH8w|+y>gpHwQo`{Wmul`I!3DV(&3*lD8(3T=H}Tu^=zP>M%Mn^iOKp## zbSKb%vb2cw$t~p4(j^*q3d<`he2o;D!oSK(0rPX%*XI=})#j6vce(X2l4&K_WLBSH z)a`XEi+Nt^)EkN7vC5Azz*8n9Vh>p|s@WqP8tlulky2^B8I@>0#y^fVJFC0d8^h3I z26-gZ5-Cuv^k5U_s0|`~tgH$Z+}-ht_G{CGwOgEWixLkK-A1;WJa$IL@@QH|H;NTb z!s>`2P_YJ)P?9$;&_00p^{^{e+cI!wb(O{a{{V@9(kBt$Es6fmyp1G)MKn{ABJy7< zSwxv}gY;Yq_VU_1k!t?{dFAGKnwWJOk=Z?c4ZGc4CD-n?DXgZloGfr(Nwwv*o%XMi zQdC|Fju(1@Nh3S~UZiwq9%YB8j-~A*u>BhHdtDb)xVD4sw=-%J$!!g;*)A3dp(*kpia`^Fk~uQC zZ1qx3E3%zug{R9T?1qv{Q=jp6k*PMZXJdD%!D)YCVH${{609z6t{Fn3M-Y#B5$=$> zbjH>BdGs>O&B?luXEr8^trVZaE|KB=8%VynyuWL|6kJZC&eA<0r${AtMU;8B5g4(v zY1xWyl&<^jENl| z@FuCM$#9k}6`_vWB(#MZSY$yfoU@t9WoFOiUQTs`p+&-kU$cTzl5*8^JsrkBj(<0J!%^g}xH<+!$+-->MHz^A!K3N~T!|n&4YR3hdQ=-1F?LDPA=6@+*j8|yxh5Ar?Y&Y zC9@_mT}}^E)MdPyJw)Cu)Y_%u%F%CQaCt#o1} z`O?0Y{Z2du7{>?lu;bhA(zX6T}WN10XZON z*1U-0F;%YVxW+fKy6x2Acz8u6EzMmT!L9YpGV}XZ`qgH-lHT)}&B>ZL+BHceA@?k8 z2_H6g^-?OZILTJ5=vIolSGpq+MMf%6dL6IBFA!;Z7PqQsdX4-Ru{wO063mJ7z{X9| zd7D0C9pWf%jALr|`BKp1Nyzj602V{5$*1Vj*(4`M)iI=hYC|EAX4dBkca;OnGAu>; z+&DGKLZzoDH`e9Gjg{Lv-wJ3R8jr-Sf23SoT>k)PSVd)db8yXrbt@U1eBd3?!ckxQ zxyMmnl^TBXl0Hv~v2T(zBeRw4Zg_cQyOQf!a1nJfk8Kd-h$96eW^Y*s&yIsWxvtpC z?&rqlEk(wX`w8FG{{WEB8p&}Vhi;>{j7v4qiq%s)bM}dn6UpiFxvHDcGPvInA1lAP z9IuIN{6#*ys9R|g`PNX}jX-IUVI=dRv_jIx$13bvME%=v%zbO-vn(|kRea0hjj!r{ zg^)tC!oqO3w2RXHmqITE>sr>mKlY5fpwnVcDHO!ze5`FdSb}ruUk#jK z@c3x^ID6F};r{>*eg0XCuZZ{RN0XONQ(IQImApxz$q2FyFWRl=lKwT35)FwYg*O!& zu^!Qr{9N%{@Z99RqFXf|yo}dL$8C=!)OBX?<^G}KPX%A5n{9P*acyS|0xOBUg$Uzx zE;Aeq{T$~V0I#=&1vsvA$;H-+NkelV!aovqO&d_KFlo`=UJ20)9sXpn$QdQJL|v-B za>_aOUes2?!f0RGeSGn`v-P*@jqxjpz9vblR(sgTOyS4i*wAx+7W6AQQxcLz-Q9_1A zb@`jncR|omB9&0 zFQ2LUeM}W8LKt}JlDxe-eeB7JAhpmMGz+{>kkW1-?m#|Wz3@QiiuBx^tAE?5`3O36 zur_IPDzaMnBXh$3Ad|zl@oPX%Vpd4*4Y!meG0VNoYv+88xa`REsKitDsiPc4FK2_N zE~}UEO`C~-;*StRdvB&{R=?TW)%i$bl}wPtZY0{t=fCeuh}$kg<#xAEl%C2JWfdAx zN5|tZR2;ssQMJkD)P84ApnMw^irPJxjzJX3Rxt)e<;@bw>J>C}{^IX-7Dw=G(0_I?8)ga>#{gMdYgB}#tN2GUM)&)azJ$7!jnULJprBuAmq&H|qaj6+nUn)6#_ps#fIuLEYv^d_5`_M#i;kOK#}*?k zi(cOj-S@GZ;ca)tx_^!|p=Ea!#ih#&HEWHiv)Z}yB=hGl_tS6gunyzXzI@E%A&wdi z$M|y9Gr?zS`(ra{UYt}kPVC{m4|L&js?QXXMY}9i z2He3|3=R)d(!9pcN+{?&Bc=Fz#oDa;KZ#(TH6B^fEG0i?S(|U~rCW%%hLSPNaSub( zbmPU;lvUz%;o%nS&A$`;Io0%&Exn|Y>$W$D@-%9R_Q;NK%*dp9$~P}6GCeU-hsPLaLo1P5u zHl3qg%CoS$(r(~bJdo0}+C&+ja>jDTJ;is0Q}?89QEw2tFc@fU);F``2~ z$(5nr<1 zgo)wO^vyO^yt#R#a#m}D_M3pk5sIN^7-lRBZI=H$HjW2flxhAwZeX8caL(uH6 z9$hZ~0K^*2wAxbY6Sdvy+<<1cvV;YO7ZH+v;{DN|ynC83*i}ZHX(#Zj9rW~vGcfLS zFAMm)N?mtbxSLKzyMHRofgG_zZJ55zBrdyzge$SyHx1lZJ$!9gRdlJw>z99DGsv%t zlb!5qYdZCW{wC6sPl8FNU$Sz2hj7Pg%}vsTZMto@C(3L#9KVF=D4wR=ISX!o8DW0UC%2JnwEzxZ*Om_c=uA*^vPP|OcBRuSS*p5 zZl^`Jk`yi%a-=FHEWgEy`aBg$!v`EZkn)(ceF{e?^ZqRXS%+EcoDN|97vrx*n#G;~Mh`_&wd+%zM+J7dx}MGk7+5Z9wC5${^!b>! zbJ|Tcy|tVo;{C~n&crAa1_Y}iSHnlN{rvRmYmLyW&+k8X@IKC2jtUfGD00cA?yt0s z{{RsDF4WJ5H5-flayv;apfXEsZwO>&bvq$hOq=&W@_@b;G$rE70KiKpuyWWB%h zkIoY1;4IKG94RtokC;Fn^`%Tb=}K^W$3wcNCz_IqIK5RPyNgu0wVc{%GD&f9r@+kd z!o{4)6t4+=h>ExffDX>wkO!GtFnrLamE^6>-_ZG-Mr{3}ryZ_&FNzO|Z?7#Qx`KbR zzVV~ll_v=8xq>S0JBu8)NpDkMOGVO(Z8he5F42y<9MdeTA&i2q4#KU*4snC{*Hm={ zs=3_QY1fhIzh<#4AYi8H8xoQ^ED&dDEsT7vw2r$?cf%w0%}qyCRX!uFhodSy-@BXs zzDIYU!J%Gh5bN5l+%0=)7nfybfWohDk1q5s;1|r2J;;a;80nVd#Gye`y1uvSdQ@Qv zE@!#Ycu&MSEu=SI8o$1WQPbUIXys-S2@-6!*2fsQR^GYkCiFNvbGt`I9;|hP*x_|M zR?{_`RMBtew@IuL?c=w)c1vqp$#*0U$P0YGCjF{enEPg@D#TEzr&6kZ?DmmD&9qVQ^RTc{R#TtK7>tH%)np}S?|+P&Jj=;2{aw-xV8 zc4tE^qetF;^n})R3!Op)^WlaaEiv{>MH}E^tGKt8L`!q!j_gw14_12G+?twVYPltS zB4ya=HyZR-(OzD(9u3f^Ysc3Zvd)Z((fy7Kr@@_Y*m;Cw`>UJ^b!()w)tpho$D5k| z=T>BR%fh}L*Ke*h+bunGtv=q>p|rD!e5SaO0|@4o1_Xb?0{!9!Ta#WK^MfYzNXoK>6}z)#9~JyOUkG1W=sIQd-OZ~+motYM`D@I=Jkrk@CFhHiw(GZPei@wG#h0~rT3!~K=*YI{n* z_zy$Mj$EfvPOJHJJx}4Ui~J3%TN^zMUefvzy6Vd1N&u=rRlnUHd3SP8o7b-6k81Rz zNkc@mKD#fK7_L|=8y-5oSbRS%y0BN&Ws1QAbRyxf<0GH-LHYuHjS@#rGIoLImtGC< zn|O~=7t&7&)NUSI2bRg+(HIEsC5|<1tn(bSXsx^D{u7a0)8}@wJgD-eX3AFDu9e}f zO5*a))>!nNS&|JxJ7}O_*6kB4F)9_dUCk^+;HVpOyuEb7qk{L0Do|A)yS?-~uk77Z zQ1I+C!*OS4Y-5URT~_W%FYYbv5kmw}=>!VCUj<5$>$zP#a1XSi$P_o+AMPZ|Mt=Cc=dh=Mn@m>1c*iSu) zlvzO}ZybAtq%s?oW_L}h7D@R$R+u_zQ%UYdCVumM2=ocfw}zy<)Eq~3s9kxN*9Ak$ zuW;&IDgaJ?Q4~rBe(zfHv6QDgN^!lSzDGQ^^Ej^@=vSI1vlg#;X%(zmn$IPkp1TXA zFtCuUv5a|d`_0VC%yLNfuVW1F1smSoPRtdl&h1}A7gM;@?LNqEtz=j(qn_R~Hq~j2 zZZdf%W;b9i0m=2Pu(Y7tirpJyGdpdytYn*8>q|3m9!0V9v2q_jXEy;FMTvO;HW{!v z{cFCYBN=kv-aI;3nWuNGZg!d`k)>)nl;c!Ml`ZXLxQ^ZlHakhWC3R*2^SI*~KY*_X z5n81<-WGoKozJ7kRdVHP-P57b={^W(Xu93c$~uyD_y)fDU$Y z4Jpy5QYp!=XZV?YTIC5mS9^DRs9x(SEyQ+nBS)d>?#*vGw^;y_=a95Yt`b7n>yEpH zYxQ`jsK>8Y*qKmBw`m`Y zlak#0y%%x)Sv}5gQt=0fF0QpXM!PhP6tL;HcTk`76pCROGL55qOwvZrwiWp>+~U0& zIC^PCsPgsmHTDtcb2_w_9whM{yq8x_mk}WI^*gy1D|a%7k|o}mTX@VUHpSGO=La>} z2C2c>Y2~?-f{v!Tj~0RuoA@cu5)PdoGe>{1y=c+a3L#} zcvW4!;N^dZ^)Yeg)ZOsf>V7HLwcC@Y!uIndg>!oDceTT!=Jw5v05cX?xMt$lN4w%^J}nryb%3Z7Rz zL0~%%PXmip7xb=mQkaA<0Gph%>u#tSrS3&olHE6_J zx)IOuSFcN#-cs62{uqh5CZxJEuC(#4hvFFYhPIGHc-OGBnsmgZ(dA?WZ8+SaxZF6e zAwjFAd%o5)w{}?Y84ab)AmL5r&&qlLt`uY270-x{!9iVE!uW-Gc@(!0+S^Ms($A(y zuM+N#GX%0oJk}eTcjIc|PHVdim8{IG%E-;R)y3zAbp0AX4SkfY&8gHir^{T+aWtmV zdzWTd*a;*qgtPON>$vpZGEiG#Fl zHtofSl1D4grD=n~dk5`c`O_6?Df_J8yhZSdv_A}7U1?X>clXwk2&A{TfqbcymCTXG zpt(gKIb_^VK9${J%0pghI+Cbs zOMf}%w`o@gY+KnDV*MFO9@sq6jXW+PHx!dM_u}<4G<%7!+!+<_8v19CQHA1yNERT@ zHi=?BX601@e9VKMJ!?9!rA1mTri~N17Qd&t(=KhSt^VD26mncy=@(JOFllzS#w_^r zA}tu|#k04NII5*rn_2ul$*C1%#F}Nlc%;>=&3mV( zhE6opUacz~9o+V|vPEF>&3~X@!q&5DGZ^PYlWqeUV_l#(-66U$TydOpV=yWn{XUwS z*mkFPJ*Jv$Zfxx)g4z^a9&>1Ax7;{nD2*l`%NtNAUEZR#qmPW0suZkYUs_8nHpc5s zwbi0V@?e_j;u6JygBJEiL-T=+_+k7@oL3EeGKalRPBE6c7)~h(<6U~g!TPMW;rd0&WpbEsa~ zT@j_*#bozz&2tczNp1)3#BoSkMcX2fn>u6=IpkN+W%#;OaWI~%PxycHJ3S;~xpw=@(Y_H_+P4CEG_7g<3mlBDYnxg~Y@Ni#o@a z%L9{NGsL+@DzlA9LzzZDi`?qN)`D$b%;iMkwcNpGZstz5QaWw#^j>6L8xw*x2! z5x7mw$4c{Zju6Jznw>?-1+UyjD>R`=JIhnYukWX{(Jd{NmLWddDH5nqXjU@KwR%C4KNmaxV zJ`Oh(21gjZ{R?#IP@<&YB0M}!E;MH@Z-p}D^qQUj0Eul)+>N4Xv)&7dpe(HtD_fC! zE6%O7ENC3NP$ zAC@nb0~%t)a9)G*BAGrw$ttJBJgA$9J#iV+AR|8 zqSti@ot~!WY_q zhh!gQwX|b@e;bK*nZ_eeH|7sL!?-27h0AwZ^=DSiL2lXcSw>q|6H(%8X>O0mYRz9_?@e3n&y)RrjS_Z;_W27 zTX7>ZELo9DyB0eY(OBU{WmfT5Z$qE^3Y{oURIe(WwqG-<(XB30((hU;GsWVtStgF+ z8*7-8FR^V_VvC1_BYoic9S;@qn2c;?S*N^Dv&yM`Uk@1h6f~>t9dzp{ygPBI!)5lB zv$fMTA1%bFB-uHHoX!MX<%?q?yo}!iPEnNQ70t_jW%{1p0}%O?Rrz}|r--y|H(l4H zj{g8q`yZ8W_Gm591lLo~APwbO#BvVglxHe?^u|XnSze|e4!I(vyx79E1gc^OaU9@)c$r+dk<5=E1y@zUluJ=~2Zl-1Rni5pg=F_I1 zBguvx^XswS>v}$wt7&s)D@g9zKrQ@Gv0K^O+sPZQUO6RT*9?)w41yiQjkz7R!_ujK zX6+uvl5tvFQ`EIE^k#Pb_g3OJT4_9FYfA<)rzBKowQ- zF_e`!wWZtpjd0JFv?o1MYhyD@u!3I+>KdKJnU7G4;%Q=QsDPR`v|tekY?S$@i%;`fPCceM_PuitY0(xk1e)3)P5>$ z2T9YPP}PAj>Iet{cnWbld?=4NBbJ*&sW;i;(m&dDE9mhly8HNB#bH!?}DLM>{` zS<`K$)3sX(>?e5|aApNitMG7CHsSJ>8*@Y@2Kk`xrHm_M+^ITkNlDIA^3>h%M}};C zNqX>V_jlG~$q%NBXw%G^NYz$Ejwv?*B1V9yPnqy>=~+~%%Kh6j3e@Y)Jo8df(Rm)H zrD*zB!wnw#;`2qg*RQ+3o}_oJuz2gv+9@-~$K{Z( z1sUE^PrimS{BF0`_1j$<>rP!0!SbIj^U9xm(#YIJ_NG-_LA&pw{{X;_+=|~F3a*=Q z_=&(_s8IJ|6%=w_KJdmY!Kliy6>3vz zq-|rP7fLaAM$%{#&+x9_TbU+~cDz|{wIX*kx?FBz;7C~)%;2AsY5V7z=k}}X4m}N1 zYMsnjd}XUat3xH1iDZF%$W&<8QxhD>t1{j~DmY5-Z4Nh~fSbj7N`qkw!jBea)Q(yjjhvBdL2x4L7(!ZU3n2Mr*`|V_y$Sbkw=kyth3Xm`ZhIr_0LXY5XpQZ>=<)E?E{^c<-9-_8t636{0H@ za>sVxws~vwedAsQTs!*Ys$1cw_`Cjxts1RUQNL5w^?P--w3hQ#xf8)?-fe)9rCAnN z4H#BRPPbR&3SSY5aB%JNJU&GFJg>(;4K;lyL%Fz?>e#^}B#?M?GhE-t0Au^Rdxy`T zAm^QcoM1P4q|D_W#~)@E;?ZQco_$4aU1w2 z-?>=6*EYFh1FK7>UN@HNsN13|J13YLCs5xxA%G&eYhfbSyQ4a(;+$W-vA5$*d%*rG z@crhaW@29u*hZ7v`Hqp_6@pFE!WA4l;T8Q<=PQxTdDwbYX;e$>oj8h+oOaan=hUrb zO|rnZDjVfjLyQ1N%e)L9Tvxn#OG8gW()=~7=^90{{RDcMn4_LVd0$?T_;qA1e;HrQ7@R? zi+R_L6w>Bzv!EVQLvbK+#1SHCaeu+=!l>~>e$Cat4K2ln;kI;t6w zbUh*mn-@2cpz^-Z(w1*7BCRxpvCDFP>aB1?GLAkj6jOrUQu6ZiX09@NHZ#N86_%ZO zub&lOTHj42%zB&N+#*35Np_nWIE0LLs5ZlI&7KEwQ;u^{ry2@ewzZdJaAR=p5=*H2 zy=%hjs`z@#!{_Y|E+>o1wT0Rd6tL}@Q!oNQ-H{tH+)v|9G-|3db#9|>yWEUCT6&GP z+aABBDs53O_K4VxxT^1si9JT#t_jZ!aa^`;oWJeY`W}%}#c6A#>X!P=_2ib;vrPYjBPxQwdmzMwLQrzufWE$<<#Znx$vZZF+rwj_j(gY0A1I_ z+-f%WTcme?v(7GKaW3w9zU(sNn)*xGUI`h{j9b*b<4s1|-%PX9^jYMz(=Hj{lT|X1 z(}=(~D{T4BWM&?0qn9LsoG}-dQKwS1rz>@0%(1@ClT@S4BZOTyPK}n%+ftE_NUfH5 z(Zc#|P_6xI?6CMO3)*`6pCwZpic0c@yzFMn4x6O>K=9MGlT8)8qFdM_1*9?V;g2Bh zUP#>CtHt6s9$P66V|`eJS{E8ldHUz@Fl3XK+;EW z@>`Q{67B_yHs;&ODnAd0rG~D#VNr9V+noxOWTR17>Th+;H%YX&u((T|F4o=y_LQF5 zRG2{u02Vdc%6!i5G6y})c1DDgyGN-!L>v;i&iFG+vD3U$tLu7_TiNPYcFT8m%u+D| zTu#c7<&Fl};ZZttdZ-_4&v;#Has=( z%Ssn|OWkTy>K6C6EhWlIrUsm}a=4Zfvoygs#y7L7l20A#FuAR1)pYfRmGo`v+39P) zCTT|r8MLI9r>1HeE|cNE53*V7H+m+Y0yI|W)BUCp?ii}9Gpyx{F((OwUH-+@nzFo^ z>sO%)P~VjvAK~wYjG9;W%*z(55nb1jS~+nc9LAEyVs%9z2{!|tTav5C6}=ov zsqRbSJ99jSSZMotQcjnf*Zv97d^Xgztx7AoR`&Por3`B64EtMY^CTPX{G|a4yD^eg z``vl2^q*73jMp>eZpT3t<+O6Vc96$+IACLR5z46JB}qAw(HM0u@=qZ2?OeE=bt)?I zmfa3aMrlTh_vNX}c)RToeUn z!?`bank}y*o;ameDs6kGOLueS#dIgmpW#hD?n|vc%0Lmu^Swl>tixIK|#!2tn(86WQ4GwARQT_*^m1MGnl;ph0eku5k?X2z^z$$9~A(^!6Td{*Q zT78l7<|zLFc|6;OVcU*t-oeJvJ-lsHn|(|jA3)T8#cgk-h@jK$SS|I$l17Yk%QCA5 zE?1VqsW=CZl-F$ZJbqidvoBh{y3jRi9}z>eYFbUqX+GWr_VXxht&i^`^Unm4+M-KC zS~B)?yiZxwZ#7+S#j!)7+q<0ypSH0v!434vGFnhFS{P2%dyOMrx7BRfHJhk>*fpzVO}cuSz#`vkGyKmM;~~pFKz8)5Xhu?9u4V4RKJver zo8r%i{t-_NPX)ED)Ec9YDp)V2SMovHU&;BH$mIY)<#-+YRYMOxZ+YlxOA$_+Qn8)z zvrxFy^j$&kB$oND-ZLhdC}y&X*)|21MBg8pT0#|LBq$kUoC?PkMY*WomNxjh+~if| zIXN@aJP)DGsCbK9j?xQlCr*19Qfn)7CB?7WT6S3rMIej`V)7-4nK9S#uAI7r>C?34 z=I^^a{9BA&&1=0kL(p~mSJyRb81D*V%4uR<(4Z&FWe*#yTXyYKgZ6r5RMY=?mCWd%gN0r-We!~M5jw1^Ss?s~~ z*oi?m9n6~_2|c_w5lgS#$8&KF(!+k+7T!y}K(k3{}RPSmU;YMI$JNIg#XOqZ>T5453Nov7FbRPXmZmbeAnV zemzT_bldJ?_{m~V3R;`H7!8h(au^HCh*nvaRVb>kqdbReNDG{dg~+XN_!^YwDc@Nm zB{;SksaD|*xjKUWSBDskUmD_1h28LzsPbLRj)eQsJouveKhjt|C|(8E!T;vPm>QyN}M4 zre*S&H}1eVZoG_FUK;_3ca;6t&8MN9sw83D>-v_r4UhJkM?BF+e#dCIdr7A|A&DUS zI~F%8@&;iufH>)z?xll`8>p@KeShJJ=DD1gGF#kT-a|a`rL;4zI)SA;)v%9qLKI4 z&gxh^L!{=S{hI1@nwNvrX_qz{J%*;*RmH+dvE{Wl39u}YDDq^UX_-PQ#LnSSaCSEp z%JVu3O>=wRjO3MnaYYz_cqYaA~2DQm6+OGNBgrG zWy&l3mjHXu%9XjO7<k_IJ%FPWU9WaFnb)r6q2OW%u$oob2;Mx44Mk(*QS-SpAi zw}|B$oy&cS^6q=5ig;v^kCQi-x-l4zbqdO(X2w5S_p=N%Xwi(QtGIoi=3PBoD8!$=aj7C;dA!H&k8Gn(}IPby5c(r7p z*78zkp}&#in#YYVuP++YL4UGok;vlGO+F9JnSI4t6^}#kx5OPoM7D|uoZaYQcS4AvVQ%aH5_3k#~ z)Z$_If#CaCUF|NlYxb2{T1GKVZ6k0uF`UEaBLy9?k3&}~bra>hY-B*~+$FY-|N_wB&VemFMCloYWNL32G^?2`W4gJN>-tz^xPn`y#oUuJ?+BtI3b<9;SHI0(ib+`_Y#u&qn6-U##9B_j z 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