gina 0.1.1-alpha.99 → 0.1.2-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README-4Contributors.md +30 -0
- package/README.md +125 -39
- package/bin/cli +130 -41
- package/bin/cli-debug +46 -15
- package/bin/cmd +63 -41
- package/bin/gina +57 -49
- package/framework/{v0.1.1-alpha.99/lib/inherits → v0.1.2-alpha.2}/LICENSE +1 -1
- package/framework/v0.1.2-alpha.2/VERSION +1 -0
- package/framework/{v0.1.1-alpha.99/core/asset/js/plugin/readme.md → v0.1.2-alpha.2/core/asset/plugin/README.md} +34 -12
- package/framework/v0.1.2-alpha.2/core/asset/plugin/dist/vendor/gina/css/gina.min.css +1 -0
- package/framework/v0.1.2-alpha.2/core/asset/plugin/dist/vendor/gina/css/gina.min.css.map +1 -0
- package/framework/v0.1.2-alpha.2/core/asset/plugin/dist/vendor/gina/html/toolbar.html +251 -0
- package/framework/{v0.1.1-alpha.99/core/asset/js/plugin/dist → v0.1.2-alpha.2/core/asset/plugin/dist/vendor/gina/js}/gina.js +4588 -3416
- package/framework/v0.1.2-alpha.2/core/asset/plugin/dist/vendor/gina/js/gina.min.js +765 -0
- package/framework/v0.1.2-alpha.2/core/asset/plugin/dist/vendor/gina/js/gina.min.js.map +8 -0
- package/framework/v0.1.2-alpha.2/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +7 -0
- package/framework/v0.1.2-alpha.2/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.map +8 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/config.js +315 -131
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/connectors/couchbase/index.js +460 -274
- package/framework/v0.1.2-alpha.2/core/connectors/couchbase/lib/connector.js +22 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/connectors/couchbase/lib/connector.v2.js +51 -51
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/connectors/couchbase/lib/connector.v3.js +51 -51
- package/framework/v0.1.2-alpha.2/core/connectors/couchbase/lib/connector.v4.js +384 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/connectors/couchbase/lib/n1ql.js +3 -2
- package/framework/v0.1.2-alpha.2/core/connectors/couchbase/lib/session-store.js +22 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/connectors/couchbase/lib/session-store.v3.js +12 -12
- package/framework/v0.1.2-alpha.2/core/connectors/couchbase/lib/session-store.v4.js +361 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/controller/controller.js +1351 -902
- package/framework/v0.1.2-alpha.2/core/controller/index.js +23 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/dev/index.js +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/dev/lib/class.js +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/dev/lib/factory.js +2 -2
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/gna.js +48 -24
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/locales/README.md +5 -0
- package/framework/v0.1.2-alpha.2/core/locales/dist/region/en.json +5727 -0
- package/framework/v0.1.2-alpha.2/core/locales/dist/region/fr.json +11452 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/locales/index.js +2 -2
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/locales/src/make.js +39 -41
- package/framework/v0.1.2-alpha.2/core/locales/src/resources/region.mapping.json +43 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/model/entity.js +87 -67
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/model/index.js +16 -16
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/model/template/entityFactory.js +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/model/template/index.js +17 -15
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/index.js +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/file/package.json +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/intl/package.json +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/intl/src/main.js +5 -5
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/storage/package.json +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/storage/src/main.js +6 -5
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/validator/package.json +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/validator/src/form-validator.js +404 -300
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/validator/src/main.js +1384 -1314
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/router.js +221 -122
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/server.express.js +69 -65
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/server.isaac.js +274 -180
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/server.js +710 -615
- package/framework/v0.1.2-alpha.2/core/template/boilerplate/bundle/config/settings.json +12 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle/config/settings.server.json +4 -4
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle/config/templates.json +4 -4
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle/controllers/controller.content.js +1 -1
- package/framework/v0.1.2-alpha.2/core/template/boilerplate/bundle/controllers/setup.js +111 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle/index.js +13 -1
- package/framework/v0.1.2-alpha.2/core/template/boilerplate/bundle_templates/html/content/homepage.html +8 -0
- package/framework/v0.1.2-alpha.2/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +11 -0
- package/framework/v0.1.2-alpha.2/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +8 -0
- package/framework/{v0.1.1-alpha.99/core/template/boilerplate/bundle_templates/html/layout → v0.1.2-alpha.2/core/template/boilerplate/bundle_templates/html/layouts}/main.html +10 -3
- package/framework/v0.1.2-alpha.2/core/template/command/gina.bat.tpl +8 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/command/gina.tpl +4 -4
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/conf/env.json +12 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/conf/manifest.json +2 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/conf/package.json +2 -2
- package/framework/v0.1.2-alpha.2/core/template/conf/statics.json +12 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/conf/templates.json +9 -9
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/helpers/console.js +3 -3
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/helpers/context.js +233 -75
- package/framework/v0.1.2-alpha.2/helpers/data/LICENSE +9 -0
- package/framework/v0.1.2-alpha.2/helpers/data/README.md +12 -0
- package/framework/v0.1.2-alpha.2/helpers/data/package.json +20 -0
- package/framework/v0.1.2-alpha.2/helpers/data/src/main.js +295 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/helpers/dateFormat.js +9 -7
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/helpers/index.js +13 -8
- package/framework/v0.1.2-alpha.2/helpers/json/LICENSE +9 -0
- package/framework/v0.1.2-alpha.2/helpers/json/README.md +12 -0
- package/framework/{v0.1.1-alpha.99/helpers/plugins → v0.1.2-alpha.2/helpers/json}/package.json +2 -2
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/helpers/json/src/main.js +33 -28
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/helpers/path.js +97 -22
- package/framework/{v0.1.1-alpha.99/helpers/json → v0.1.2-alpha.2/helpers/plugins}/package.json +2 -2
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/helpers/plugins/src/api-error.js +23 -23
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/helpers/plugins/src/main.js +3 -3
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/helpers/prototypes.js +46 -38
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/helpers/text.js +2 -2
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/archiver/package.json +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/archiver/src/dep/jszip.min.js +3 -3
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/archiver/src/main.js +183 -168
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/aliases.json +4 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/bundle/add.js +84 -28
- package/framework/v0.1.2-alpha.2/lib/cmd/bundle/arguments.json +8 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/bundle/help.txt +4 -2
- package/framework/v0.1.2-alpha.2/lib/cmd/bundle/list.js +175 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/bundle/remove.js +39 -27
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/bundle/restart.js +14 -8
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/bundle/start.js +283 -49
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/bundle/stop.js +93 -74
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/env/add.js +87 -49
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/env/list.js +26 -4
- package/framework/{v0.1.1-alpha.99/lib/cmd/scope → v0.1.2-alpha.2/lib/cmd/env}/remove.js +29 -24
- package/framework/v0.1.2-alpha.2/lib/cmd/env/use.js +106 -0
- package/framework/v0.1.2-alpha.2/lib/cmd/framework/build.js +93 -0
- package/framework/v0.1.2-alpha.2/lib/cmd/framework/init.js +932 -0
- package/framework/v0.1.2-alpha.2/lib/cmd/framework/link-node-modules.js +123 -0
- package/framework/v0.1.2-alpha.2/lib/cmd/framework/link.js +137 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/framework/open.js +25 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/framework/restart.js +78 -26
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/framework/set.js +120 -40
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/framework/start.js +49 -20
- package/framework/v0.1.2-alpha.2/lib/cmd/framework/status.js +144 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/framework/stop.js +64 -31
- package/framework/v0.1.2-alpha.2/lib/cmd/framework/tail.js +303 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/framework/version.js +19 -4
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/helper.js +357 -53
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/index.js +23 -23
- package/framework/v0.1.2-alpha.2/lib/cmd/port/inc/scan.js +142 -0
- package/framework/v0.1.2-alpha.2/lib/cmd/port/list.js +464 -0
- package/framework/v0.1.2-alpha.2/lib/cmd/port/reset.js +417 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/add.js +344 -157
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/arguments.json +2 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/build.js +28 -28
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/help.txt +7 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/list.js +22 -2
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/remove.js +19 -17
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/rename.js +11 -11
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/protocol/set.js +260 -211
- package/framework/v0.1.2-alpha.2/lib/cmd/scope/add.js +129 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/scope/help.txt +4 -4
- package/framework/{v0.1.1-alpha.99/lib/cmd/env/use.js → v0.1.2-alpha.2/lib/cmd/scope/link-production.js} +22 -21
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/scope/list.js +34 -11
- package/framework/v0.1.2-alpha.2/lib/cmd/scope/remove.js +122 -0
- package/framework/v0.1.2-alpha.2/lib/cmd/scope/use.js +68 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/view/add.js +35 -10
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/collection/package.json +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/collection/src/main.js +247 -244
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/config.js +33 -31
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cron/package.json +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cron/src/main.js +16 -11
- package/framework/v0.1.2-alpha.2/lib/domain/LICENSE +9 -0
- package/framework/v0.1.2-alpha.2/lib/domain/README.md +46 -0
- package/framework/v0.1.2-alpha.2/lib/domain/dist/public_suffix_list.dat +14186 -0
- package/framework/v0.1.2-alpha.2/lib/domain/package.json +20 -0
- package/framework/v0.1.2-alpha.2/lib/domain/src/main.js +442 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/generator/index.js +5 -5
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/index.js +3 -2
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2/lib/inherits}/LICENSE +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/inherits/README.md +2 -2
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/inherits/package.json +3 -4
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/inherits/src/main.js +3 -3
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/logger/package.json +2 -2
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/logger/src/containers/default/index.js +15 -2
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/logger/src/containers/file/index.js +109 -14
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/logger/src/containers/mq/index.js +12 -3
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/logger/src/containers/mq/listener.js +29 -21
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/logger/src/containers/mq/speaker.js +33 -4
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/logger/src/helper.js +22 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/logger/src/main.js +36 -9
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/math/index.js +9 -9
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/merge/README.md +2 -2
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/merge/package.json +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/merge/src/main.js +118 -91
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/model.js +10 -10
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/proc.js +92 -49
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/routing/package.json +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/routing/src/main.js +377 -420
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/session-store.js +13 -7
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/shell.js +3 -3
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/swig-filters/package.json +1 -1
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/swig-filters/src/main.js +140 -119
- package/framework/v0.1.2-alpha.2/lib/url/README.md +0 -0
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/validator.js +2 -2
- package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/package.json +1 -1
- package/package.json +10 -10
- package/resources/home/main.json +39 -5
- package/resources/home/settings.json +8 -0
- package/resources/package.json.template +1 -1
- package/script/lib.js +0 -0
- package/script/post_install.js +179 -89
- package/script/pre_install.js +95 -12
- package/services/.gna/67fdf1b224a2ed5597e63d4b64283834468e05e3.txt +0 -0
- package/services/.gna/arch +1 -0
- package/services/.gna/locals.json +14 -0
- package/services/.gna/platform +1 -0
- package/services/configure +6 -0
- package/services/env.json +18 -0
- package/services/manifest.json +30 -0
- package/services/package.json +11 -0
- package/services/src/proxy/config/app.json +6 -0
- package/services/src/proxy/config/routing.json +11 -0
- package/services/src/proxy/config/settings.json +9 -0
- package/services/src/proxy/config/settings.server.json +31 -0
- package/services/src/proxy/config/statics.json +3 -0
- package/services/src/proxy/controllers/controller.content.js +58 -0
- package/services/src/proxy/controllers/controller.js +30 -0
- package/{framework/v0.1.1-alpha.99/core/template/boilerplate/bundle → services/src/proxy}/controllers/setup.js +14 -14
- package/services/src/proxy/index.js +31 -0
- package/services/src/proxy/lib/domain/README.md +48 -0
- package/services/src/proxy/lib/domain/src/config/public_suffix_list.dat +14186 -0
- package/services/src/toolbar/config/app.json +6 -0
- package/services/src/toolbar/config/routing.json +11 -0
- package/{framework/v0.1.1-alpha.99/core/template/boilerplate/bundle → services/src/toolbar}/config/settings.json +0 -0
- package/services/src/toolbar/config/settings.server.json +30 -0
- package/services/src/toolbar/controllers/controller.content.js +39 -0
- package/services/src/toolbar/controllers/controller.js +30 -0
- package/services/src/toolbar/controllers/setup.js +111 -0
- package/services/src/toolbar/index.js +43 -0
- package/utils/helper.js +25 -156
- package/utils/prototypes.js +9 -9
- package/utils/prototypes.json_clone.js +70 -37
- package/framework/v0.1.1-alpha.99/VERSION +0 -1
- package/framework/v0.1.1-alpha.99/core/asset/js/plugin/dist/gina.js.map +0 -56
- package/framework/v0.1.1-alpha.99/core/asset/js/plugin/dist/gina.min.css +0 -1
- package/framework/v0.1.1-alpha.99/core/asset/js/plugin/dist/gina.min.css.map +0 -1
- package/framework/v0.1.1-alpha.99/core/asset/js/plugin/dist/gina.min.js +0 -736
- package/framework/v0.1.1-alpha.99/core/asset/js/plugin/dist/gina.min.js.map +0 -56
- package/framework/v0.1.1-alpha.99/core/asset/js/plugin/dist/gina.onload.min.js +0 -5
- package/framework/v0.1.1-alpha.99/core/asset/js/plugin/dist/gina.onload.min.js.map +0 -8
- package/framework/v0.1.1-alpha.99/core/connectors/couchbase/lib/connector.js +0 -20
- package/framework/v0.1.1-alpha.99/core/connectors/couchbase/lib/session-store.js +0 -21
- package/framework/v0.1.1-alpha.99/core/controller/index.js +0 -27
- package/framework/v0.1.1-alpha.99/core/locales/dist/region/en.json +0 -9492
- package/framework/v0.1.1-alpha.99/core/locales/dist/region/fr.json +0 -9492
- package/framework/v0.1.1-alpha.99/core/locales/src/resources/region.mapping.json +0 -28
- package/framework/v0.1.1-alpha.99/core/template/boilerplate/bundle_templates/html/homepage.html +0 -4
- package/framework/v0.1.1-alpha.99/core/template/conf/statics.json +0 -10
- package/framework/v0.1.1-alpha.99/lib/cmd/bundle/arguments.json +0 -4
- package/framework/v0.1.1-alpha.99/lib/cmd/bundle/list.js +0 -129
- package/framework/v0.1.1-alpha.99/lib/cmd/env/remove.js +0 -150
- package/framework/v0.1.1-alpha.99/lib/cmd/framework/init.js +0 -541
- package/framework/v0.1.1-alpha.99/lib/cmd/framework/status.js +0 -72
- package/framework/v0.1.1-alpha.99/lib/cmd/framework/tail.js +0 -184
- package/framework/v0.1.1-alpha.99/lib/cmd/port/inc/scan.js +0 -108
- package/framework/v0.1.1-alpha.99/lib/cmd/port/list.js +0 -176
- package/framework/v0.1.1-alpha.99/lib/cmd/scope/set.js +0 -57
- package/framework/v0.1.1-alpha.99/lib/cmd/scope/unset.js +0 -44
- package/framework/v0.1.1-alpha.99/lib/cmd/scope/use.js +0 -79
- package/script/post_publish.js +0 -185
- package/script/prepare_version.js +0 -552
- /package/{framework/v0.1.1-alpha.99/core/template/command/gina.bat.tpl → bin/gina.bat} +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/AUTHORS +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/asset/html/nolayout.html +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/asset/html/static.html +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/asset/img/android-chrome-192x192.png +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/asset/img/android-chrome-512x512.png +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/asset/img/apple-touch-icon.png +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/asset/img/favicon-16x16.png +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/asset/img/favicon-32x32.png +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/asset/img/favicon.ico +0 -0
- /package/framework/{v0.1.1-alpha.99/core/asset/js → v0.1.2-alpha.2/core/asset}/plugin/uuid.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/connectors/couchbase/lib/session-store.v2.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/controller/controller.framework.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/deps/busboy/.travis.yml +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/deps/busboy/LICENSE +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/deps/busboy/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/deps/busboy/deps/encoding/encoding-indexes.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/deps/busboy/deps/encoding/encoding.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/deps/busboy/lib/main.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/deps/busboy/lib/types/multipart.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/deps/busboy/lib/types/urlencoded.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/deps/busboy/lib/utils.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/deps/busboy/package.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/deps/swig-client/swig-2.0.0.min.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/dev/lib/tools.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/locales/currency.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/locales/dist/language/en.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/locales/dist/language/fr.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/locales/src/resources/currency.csv +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/locales/src/resources/region.csv +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/mime.types +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/file/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/file/build.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/intl/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/intl/build.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/storage/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/storage/build.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/validator/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/plugins/lib/validator/build.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/status.codes +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle/config/app.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle/config/routing.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle_public/css/default.css +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle_public/readme.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/conf/settings.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/error/client/json/401.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/error/client/json/403.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/error/client/json/404.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/error/server/html/50x.html +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/error/server/json/500.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/error/server/json/503.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/core/template/extensions/logger/config.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/helpers/plugins/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/helpers/task.js +0 -0
- /package/framework/{v0.1.1-alpha.99/helpers/json → v0.1.2-alpha.2/lib/archiver}/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/archiver/build.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/bundle/copy.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/bundle/cp.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/bundle/help.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/bundle/rename.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/bundle/rm.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/bundle/status.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/env/get.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/env/help.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/env/help.txt +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/env/link-dev.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/env/rm.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/env/set.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/env/unset.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/framework/dot.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/framework/get.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/framework/help.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/framework/help.txt +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/framework/msg.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/framework/update.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/gina-dev.1.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/gina-framework.1.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/gina.1.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/msg.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/port/help.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/port/help.txt +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/port/set.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/help.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/import.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/move.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/restart.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/rm.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/start.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/status.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/project/stop.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/protocol/help.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/protocol/help.txt +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/protocol/list.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/scope/help.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/scope/link-local.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cmd/scope/rm.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/collection/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/collection/build.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/cron/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99/lib/archiver/README.md → v0.1.2-alpha.2/lib/domain/exemples/backend.js} +0 -0
- /package/framework/{v0.1.1-alpha.99/lib/routing/README.md → v0.1.2-alpha.2/lib/domain/exemples/frontend.html} +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/inherits/example/inheriting_eventemitter.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/inherits/example/protected_inheritance.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/inherits/example/simple_inheritance.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/inherits/example/super_attribute_overridden_by_child_on_init.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/logger/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/merge/example/merge.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/merge/example/merge_2_literal objects.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/merge/example/merge_and_preserve_first.js +0 -0
- /package/framework/{v0.1.1-alpha.99/lib/swig-filters → v0.1.2-alpha.2/lib/routing}/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/routing/build.json +0 -0
- /package/framework/{v0.1.1-alpha.99/lib/url → v0.1.2-alpha.2/lib/swig-filters}/README.md +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/url/index.js +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/url/mocks.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/url/routing.json +0 -0
- /package/framework/{v0.1.1-alpha.99 → v0.1.2-alpha.2}/lib/url/test.js +0 -0
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": [
|
|
4
|
-
"../../../../../node_modules/requirejs/require.js",
|
|
5
|
-
"../../../../../node_modules/uuid/dist/umd/uuid.min.js",
|
|
6
|
-
"../../../../../lib/merge/src/main.js",
|
|
7
|
-
"gina/utils/events.js",
|
|
8
|
-
"../../../../../helpers/prototypes.js",
|
|
9
|
-
"../../../../../helpers/dateFormat.js",
|
|
10
|
-
"vendor/jquery/1.12.4.min.js",
|
|
11
|
-
"../../../../../lib/collection/src/main.js",
|
|
12
|
-
"../../../../plugins/lib/validator/src/form-validator.js",
|
|
13
|
-
"../../../../../lib/routing/src/main.js",
|
|
14
|
-
"../../../../plugins/lib/storage/src/main.js",
|
|
15
|
-
"gina/utils/dom.js",
|
|
16
|
-
"../../../../plugins/lib/validator/src/main.js",
|
|
17
|
-
"gina/toolbar/main.js",
|
|
18
|
-
"gina/main.js",
|
|
19
|
-
"../../../../../node_modules/engine.io-client/dist/engine.io.min.js",
|
|
20
|
-
"gina/helpers/binding.js",
|
|
21
|
-
"gina/link/main.js",
|
|
22
|
-
"gina/popin/main.js",
|
|
23
|
-
"gina/utils/effects.js",
|
|
24
|
-
"gina/utils/polyfill.js",
|
|
25
|
-
"../../../../../lib/inherits/src/main.js",
|
|
26
|
-
"main.js"
|
|
27
|
-
],
|
|
28
|
-
"names": [],
|
|
29
|
-
"mappings": "AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACpmEA;AACA,ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACnhBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,AC14BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACxNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,AChhBA;AACA;AACA;AACA;AACA;AACA,ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACn7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACluDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACp9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,AC3aA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACtwNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACtgDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACheA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACznDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,AC9GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,AC/FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA",
|
|
30
|
-
"file": "gina.min.js",
|
|
31
|
-
"sourcesContent": [
|
|
32
|
-
"/** vim: et:ts=4:sw=4:sts=4\n * @license RequireJS 2.3.6 Copyright jQuery Foundation and other contributors.\n * Released under MIT license, https://github.com/requirejs/requirejs/blob/master/LICENSE\n */\n//Not using strict: uneven strict support in browsers, #392, and causes\n//problems with requirejs.exec()/transpiler plugins that may not be strict.\n/*jslint regexp: true, nomen: true, sloppy: true */\n/*global window, navigator, document, importScripts, setTimeout, opera */\n\nvar requirejs, require, define;\n(function (global, setTimeout) {\n var req, s, head, baseElement, dataMain, src,\n interactiveScript, currentlyAddingScript, mainScript, subPath,\n version = '2.3.6',\n commentRegExp = /\\/\\*[\\s\\S]*?\\*\\/|([^:\"'=]|^)\\/\\/.*$/mg,\n cjsRequireRegExp = /[^.]\\s*require\\s*\\(\\s*[\"']([^'\"\\s]+)[\"']\\s*\\)/g,\n jsSuffixRegExp = /\\.js$/,\n currDirRegExp = /^\\.\\//,\n op = Object.prototype,\n ostring = op.toString,\n hasOwn = op.hasOwnProperty,\n isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document),\n isWebWorker = !isBrowser && typeof importScripts !== 'undefined',\n //PS3 indicates loaded and complete, but need to wait for complete\n //specifically. Sequence is 'loading', 'loaded', execution,\n // then 'complete'. The UA check is unfortunate, but not sure how\n //to feature test w/o causing perf issues.\n readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ?\n /^complete$/ : /^(complete|loaded)$/,\n defContextName = '_',\n //Oh the tragedy, detecting opera. See the usage of isOpera for reason.\n isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]',\n contexts = {},\n cfg = {},\n globalDefQueue = [],\n useInteractive = false;\n\n //Could match something like ')//comment', do not lose the prefix to comment.\n function commentReplace(match, singlePrefix) {\n return singlePrefix || '';\n }\n\n function isFunction(it) {\n return ostring.call(it) === '[object Function]';\n }\n\n function isArray(it) {\n return ostring.call(it) === '[object Array]';\n }\n\n /**\n * Helper function for iterating over an array. If the func returns\n * a true value, it will break out of the loop.\n */\n function each(ary, func) {\n if (ary) {\n var i;\n for (i = 0; i < ary.length; i += 1) {\n if (ary[i] && func(ary[i], i, ary)) {\n break;\n }\n }\n }\n }\n\n /**\n * Helper function for iterating over an array backwards. If the func\n * returns a true value, it will break out of the loop.\n */\n function eachReverse(ary, func) {\n if (ary) {\n var i;\n for (i = ary.length - 1; i > -1; i -= 1) {\n if (ary[i] && func(ary[i], i, ary)) {\n break;\n }\n }\n }\n }\n\n function hasProp(obj, prop) {\n return hasOwn.call(obj, prop);\n }\n\n function getOwn(obj, prop) {\n return hasProp(obj, prop) && obj[prop];\n }\n\n /**\n * Cycles over properties in an object and calls a function for each\n * property value. If the function returns a truthy value, then the\n * iteration is stopped.\n */\n function eachProp(obj, func) {\n var prop;\n for (prop in obj) {\n if (hasProp(obj, prop)) {\n if (func(obj[prop], prop)) {\n break;\n }\n }\n }\n }\n\n /**\n * Simple function to mix in properties from source into target,\n * but only if target does not already have a property of the same name.\n */\n function mixin(target, source, force, deepStringMixin) {\n if (source) {\n eachProp(source, function (value, prop) {\n if (force || !hasProp(target, prop)) {\n if (deepStringMixin && typeof value === 'object' && value &&\n !isArray(value) && !isFunction(value) &&\n !(value instanceof RegExp)) {\n\n if (!target[prop]) {\n target[prop] = {};\n }\n mixin(target[prop], value, force, deepStringMixin);\n } else {\n target[prop] = value;\n }\n }\n });\n }\n return target;\n }\n\n //Similar to Function.prototype.bind, but the 'this' object is specified\n //first, since it is easier to read/figure out what 'this' will be.\n function bind(obj, fn) {\n return function () {\n return fn.apply(obj, arguments);\n };\n }\n\n function scripts() {\n return document.getElementsByTagName('script');\n }\n\n function defaultOnError(err) {\n throw err;\n }\n\n //Allow getting a global that is expressed in\n //dot notation, like 'a.b.c'.\n function getGlobal(value) {\n if (!value) {\n return value;\n }\n var g = global;\n each(value.split('.'), function (part) {\n g = g[part];\n });\n return g;\n }\n\n /**\n * Constructs an error with a pointer to an URL with more information.\n * @param {String} id the error ID that maps to an ID on a web page.\n * @param {String} message human readable error.\n * @param {Error} [err] the original error, if there is one.\n *\n * @returns {Error}\n */\n function makeError(id, msg, err, requireModules) {\n var e = new Error(msg + '\\nhttps://requirejs.org/docs/errors.html#' + id);\n e.requireType = id;\n e.requireModules = requireModules;\n if (err) {\n e.originalError = err;\n }\n return e;\n }\n\n if (typeof define !== 'undefined') {\n //If a define is already in play via another AMD loader,\n //do not overwrite.\n return;\n }\n\n if (typeof requirejs !== 'undefined') {\n if (isFunction(requirejs)) {\n //Do not overwrite an existing requirejs instance.\n return;\n }\n cfg = requirejs;\n requirejs = undefined;\n }\n\n //Allow for a require config object\n if (typeof require !== 'undefined' && !isFunction(require)) {\n //assume it is a config object.\n cfg = require;\n require = undefined;\n }\n\n function newContext(contextName) {\n var inCheckLoaded, Module, context, handlers,\n checkLoadedTimeoutId,\n config = {\n //Defaults. Do not set a default for map\n //config to speed up normalize(), which\n //will run faster if there is no default.\n waitSeconds: 7,\n baseUrl: './',\n paths: {},\n bundles: {},\n pkgs: {},\n shim: {},\n config: {}\n },\n registry = {},\n //registry of just enabled modules, to speed\n //cycle breaking code when lots of modules\n //are registered, but not activated.\n enabledRegistry = {},\n undefEvents = {},\n defQueue = [],\n defined = {},\n urlFetched = {},\n bundlesMap = {},\n requireCounter = 1,\n unnormalizedCounter = 1;\n\n /**\n * Trims the . and .. from an array of path segments.\n * It will keep a leading path segment if a .. will become\n * the first path segment, to help with module name lookups,\n * which act like paths, but can be remapped. But the end result,\n * all paths that use this function should look normalized.\n * NOTE: this method MODIFIES the input array.\n * @param {Array} ary the array of path segments.\n */\n function trimDots(ary) {\n var i, part;\n for (i = 0; i < ary.length; i++) {\n part = ary[i];\n if (part === '.') {\n ary.splice(i, 1);\n i -= 1;\n } else if (part === '..') {\n // If at the start, or previous value is still ..,\n // keep them so that when converted to a path it may\n // still work when converted to a path, even though\n // as an ID it is less than ideal. In larger point\n // releases, may be better to just kick out an error.\n if (i === 0 || (i === 1 && ary[2] === '..') || ary[i - 1] === '..') {\n continue;\n } else if (i > 0) {\n ary.splice(i - 1, 2);\n i -= 2;\n }\n }\n }\n }\n\n /**\n * Given a relative module name, like ./something, normalize it to\n * a real name that can be mapped to a path.\n * @param {String} name the relative name\n * @param {String} baseName a real name that the name arg is relative\n * to.\n * @param {Boolean} applyMap apply the map config to the value. Should\n * only be done if this normalization is for a dependency ID.\n * @returns {String} normalized name\n */\n function normalize(name, baseName, applyMap) {\n var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex,\n foundMap, foundI, foundStarMap, starI, normalizedBaseParts,\n baseParts = (baseName && baseName.split('/')),\n map = config.map,\n starMap = map && map['*'];\n\n //Adjust any relative paths.\n if (name) {\n name = name.split('/');\n lastIndex = name.length - 1;\n\n // If wanting node ID compatibility, strip .js from end\n // of IDs. Have to do this here, and not in nameToUrl\n // because node allows either .js or non .js to map\n // to same file.\n if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {\n name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');\n }\n\n // Starts with a '.' so need the baseName\n if (name[0].charAt(0) === '.' && baseParts) {\n //Convert baseName to array, and lop off the last part,\n //so that . matches that 'directory' and not name of the baseName's\n //module. For instance, baseName of 'one/two/three', maps to\n //'one/two/three.js', but we want the directory, 'one/two' for\n //this normalization.\n normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);\n name = normalizedBaseParts.concat(name);\n }\n\n trimDots(name);\n name = name.join('/');\n }\n\n //Apply map config if available.\n if (applyMap && map && (baseParts || starMap)) {\n nameParts = name.split('/');\n\n outerLoop: for (i = nameParts.length; i > 0; i -= 1) {\n nameSegment = nameParts.slice(0, i).join('/');\n\n if (baseParts) {\n //Find the longest baseName segment match in the config.\n //So, do joins on the biggest to smallest lengths of baseParts.\n for (j = baseParts.length; j > 0; j -= 1) {\n mapValue = getOwn(map, baseParts.slice(0, j).join('/'));\n\n //baseName segment has config, find if it has one for\n //this name.\n if (mapValue) {\n mapValue = getOwn(mapValue, nameSegment);\n if (mapValue) {\n //Match, update name to the new value.\n foundMap = mapValue;\n foundI = i;\n break outerLoop;\n }\n }\n }\n }\n\n //Check for a star map match, but just hold on to it,\n //if there is a shorter segment match later in a matching\n //config, then favor over this star map.\n if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) {\n foundStarMap = getOwn(starMap, nameSegment);\n starI = i;\n }\n }\n\n if (!foundMap && foundStarMap) {\n foundMap = foundStarMap;\n foundI = starI;\n }\n\n if (foundMap) {\n nameParts.splice(0, foundI, foundMap);\n name = nameParts.join('/');\n }\n }\n\n // If the name points to a package's name, use\n // the package main instead.\n pkgMain = getOwn(config.pkgs, name);\n\n return pkgMain ? pkgMain : name;\n }\n\n function removeScript(name) {\n if (isBrowser) {\n each(scripts(), function (scriptNode) {\n if (scriptNode.getAttribute('data-requiremodule') === name &&\n scriptNode.getAttribute('data-requirecontext') === context.contextName) {\n scriptNode.parentNode.removeChild(scriptNode);\n return true;\n }\n });\n }\n }\n\n function hasPathFallback(id) {\n var pathConfig = getOwn(config.paths, id);\n if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {\n //Pop off the first array value, since it failed, and\n //retry\n pathConfig.shift();\n context.require.undef(id);\n\n //Custom require that does not do map translation, since\n //ID is \"absolute\", already mapped/resolved.\n context.makeRequire(null, {\n skipMap: true\n })([id]);\n\n return true;\n }\n }\n\n //Turns a plugin!resource to [plugin, resource]\n //with the plugin being undefined if the name\n //did not have a plugin prefix.\n function splitPrefix(name) {\n var prefix,\n index = name ? name.indexOf('!') : -1;\n if (index > -1) {\n prefix = name.substring(0, index);\n name = name.substring(index + 1, name.length);\n }\n return [prefix, name];\n }\n\n /**\n * Creates a module mapping that includes plugin prefix, module\n * name, and path. If parentModuleMap is provided it will\n * also normalize the name via require.normalize()\n *\n * @param {String} name the module name\n * @param {String} [parentModuleMap] parent module map\n * for the module name, used to resolve relative names.\n * @param {Boolean} isNormalized: is the ID already normalized.\n * This is true if this call is done for a define() module ID.\n * @param {Boolean} applyMap: apply the map config to the ID.\n * Should only be true if this map is for a dependency.\n *\n * @returns {Object}\n */\n function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {\n var url, pluginModule, suffix, nameParts,\n prefix = null,\n parentName = parentModuleMap ? parentModuleMap.name : null,\n originalName = name,\n isDefine = true,\n normalizedName = '';\n\n //If no name, then it means it is a require call, generate an\n //internal name.\n if (!name) {\n isDefine = false;\n name = '_@r' + (requireCounter += 1);\n }\n\n nameParts = splitPrefix(name);\n prefix = nameParts[0];\n name = nameParts[1];\n\n if (prefix) {\n prefix = normalize(prefix, parentName, applyMap);\n pluginModule = getOwn(defined, prefix);\n }\n\n //Account for relative paths if there is a base name.\n if (name) {\n if (prefix) {\n if (isNormalized) {\n normalizedName = name;\n } else if (pluginModule && pluginModule.normalize) {\n //Plugin is loaded, use its normalize method.\n normalizedName = pluginModule.normalize(name, function (name) {\n return normalize(name, parentName, applyMap);\n });\n } else {\n // If nested plugin references, then do not try to\n // normalize, as it will not normalize correctly. This\n // places a restriction on resourceIds, and the longer\n // term solution is not to normalize until plugins are\n // loaded and all normalizations to allow for async\n // loading of a loader plugin. But for now, fixes the\n // common uses. Details in #1131\n normalizedName = name.indexOf('!') === -1 ?\n normalize(name, parentName, applyMap) :\n name;\n }\n } else {\n //A regular module.\n normalizedName = normalize(name, parentName, applyMap);\n\n //Normalized name may be a plugin ID due to map config\n //application in normalize. The map config values must\n //already be normalized, so do not need to redo that part.\n nameParts = splitPrefix(normalizedName);\n prefix = nameParts[0];\n normalizedName = nameParts[1];\n isNormalized = true;\n\n url = context.nameToUrl(normalizedName);\n }\n }\n\n //If the id is a plugin id that cannot be determined if it needs\n //normalization, stamp it with a unique ID so two matching relative\n //ids that may conflict can be separate.\n suffix = prefix && !pluginModule && !isNormalized ?\n '_unnormalized' + (unnormalizedCounter += 1) :\n '';\n\n return {\n prefix: prefix,\n name: normalizedName,\n parentMap: parentModuleMap,\n unnormalized: !!suffix,\n url: url,\n originalName: originalName,\n isDefine: isDefine,\n id: (prefix ?\n prefix + '!' + normalizedName :\n normalizedName) + suffix\n };\n }\n\n function getModule(depMap) {\n var id = depMap.id,\n mod = getOwn(registry, id);\n\n if (!mod) {\n mod = registry[id] = new context.Module(depMap);\n }\n\n return mod;\n }\n\n function on(depMap, name, fn) {\n var id = depMap.id,\n mod = getOwn(registry, id);\n\n if (hasProp(defined, id) &&\n (!mod || mod.defineEmitComplete)) {\n if (name === 'defined') {\n fn(defined[id]);\n }\n } else {\n mod = getModule(depMap);\n if (mod.error && name === 'error') {\n fn(mod.error);\n } else {\n mod.on(name, fn);\n }\n }\n }\n\n function onError(err, errback) {\n var ids = err.requireModules,\n notified = false;\n\n if (errback) {\n errback(err);\n } else {\n each(ids, function (id) {\n var mod = getOwn(registry, id);\n if (mod) {\n //Set error on module, so it skips timeout checks.\n mod.error = err;\n if (mod.events.error) {\n notified = true;\n mod.emit('error', err);\n }\n }\n });\n\n if (!notified) {\n req.onError(err);\n }\n }\n }\n\n /**\n * Internal method to transfer globalQueue items to this context's\n * defQueue.\n */\n function takeGlobalQueue() {\n //Push all the globalDefQueue items into the context's defQueue\n if (globalDefQueue.length) {\n each(globalDefQueue, function(queueItem) {\n var id = queueItem[0];\n if (typeof id === 'string') {\n context.defQueueMap[id] = true;\n }\n defQueue.push(queueItem);\n });\n globalDefQueue = [];\n }\n }\n\n handlers = {\n 'require': function (mod) {\n if (mod.require) {\n return mod.require;\n } else {\n return (mod.require = context.makeRequire(mod.map));\n }\n },\n 'exports': function (mod) {\n mod.usingExports = true;\n if (mod.map.isDefine) {\n if (mod.exports) {\n return (defined[mod.map.id] = mod.exports);\n } else {\n return (mod.exports = defined[mod.map.id] = {});\n }\n }\n },\n 'module': function (mod) {\n if (mod.module) {\n return mod.module;\n } else {\n return (mod.module = {\n id: mod.map.id,\n uri: mod.map.url,\n config: function () {\n return getOwn(config.config, mod.map.id) || {};\n },\n exports: mod.exports || (mod.exports = {})\n });\n }\n }\n };\n\n function cleanRegistry(id) {\n //Clean up machinery used for waiting modules.\n delete registry[id];\n delete enabledRegistry[id];\n }\n\n function breakCycle(mod, traced, processed) {\n var id = mod.map.id;\n\n if (mod.error) {\n mod.emit('error', mod.error);\n } else {\n traced[id] = true;\n each(mod.depMaps, function (depMap, i) {\n var depId = depMap.id,\n dep = getOwn(registry, depId);\n\n //Only force things that have not completed\n //being defined, so still in the registry,\n //and only if it has not been matched up\n //in the module already.\n if (dep && !mod.depMatched[i] && !processed[depId]) {\n if (getOwn(traced, depId)) {\n mod.defineDep(i, defined[depId]);\n mod.check(); //pass false?\n } else {\n breakCycle(dep, traced, processed);\n }\n }\n });\n processed[id] = true;\n }\n }\n\n function checkLoaded() {\n var err, usingPathFallback,\n waitInterval = config.waitSeconds * 1000,\n //It is possible to disable the wait interval by using waitSeconds of 0.\n expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),\n noLoads = [],\n reqCalls = [],\n stillLoading = false,\n needCycleCheck = true;\n\n //Do not bother if this call was a result of a cycle break.\n if (inCheckLoaded) {\n return;\n }\n\n inCheckLoaded = true;\n\n //Figure out the state of all the modules.\n eachProp(enabledRegistry, function (mod) {\n var map = mod.map,\n modId = map.id;\n\n //Skip things that are not enabled or in error state.\n if (!mod.enabled) {\n return;\n }\n\n if (!map.isDefine) {\n reqCalls.push(mod);\n }\n\n if (!mod.error) {\n //If the module should be executed, and it has not\n //been inited and time is up, remember it.\n if (!mod.inited && expired) {\n if (hasPathFallback(modId)) {\n usingPathFallback = true;\n stillLoading = true;\n } else {\n noLoads.push(modId);\n removeScript(modId);\n }\n } else if (!mod.inited && mod.fetched && map.isDefine) {\n stillLoading = true;\n if (!map.prefix) {\n //No reason to keep looking for unfinished\n //loading. If the only stillLoading is a\n //plugin resource though, keep going,\n //because it may be that a plugin resource\n //is waiting on a non-plugin cycle.\n return (needCycleCheck = false);\n }\n }\n }\n });\n\n if (expired && noLoads.length) {\n //If wait time expired, throw error of unloaded modules.\n err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads);\n err.contextName = context.contextName;\n return onError(err);\n }\n\n //Not expired, check for a cycle.\n if (needCycleCheck) {\n each(reqCalls, function (mod) {\n breakCycle(mod, {}, {});\n });\n }\n\n //If still waiting on loads, and the waiting load is something\n //other than a plugin resource, or there are still outstanding\n //scripts, then just try back later.\n if ((!expired || usingPathFallback) && stillLoading) {\n //Something is still waiting to load. Wait for it, but only\n //if a timeout is not already in effect.\n if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {\n checkLoadedTimeoutId = setTimeout(function () {\n checkLoadedTimeoutId = 0;\n checkLoaded();\n }, 50);\n }\n }\n\n inCheckLoaded = false;\n }\n\n Module = function (map) {\n this.events = getOwn(undefEvents, map.id) || {};\n this.map = map;\n this.shim = getOwn(config.shim, map.id);\n this.depExports = [];\n this.depMaps = [];\n this.depMatched = [];\n this.pluginMaps = {};\n this.depCount = 0;\n\n /* this.exports this.factory\n this.depMaps = [],\n this.enabled, this.fetched\n */\n };\n\n Module.prototype = {\n init: function (depMaps, factory, errback, options) {\n options = options || {};\n\n //Do not do more inits if already done. Can happen if there\n //are multiple define calls for the same module. That is not\n //a normal, common case, but it is also not unexpected.\n if (this.inited) {\n return;\n }\n\n this.factory = factory;\n\n if (errback) {\n //Register for errors on this module.\n this.on('error', errback);\n } else if (this.events.error) {\n //If no errback already, but there are error listeners\n //on this module, set up an errback to pass to the deps.\n errback = bind(this, function (err) {\n this.emit('error', err);\n });\n }\n\n //Do a copy of the dependency array, so that\n //source inputs are not modified. For example\n //\"shim\" deps are passed in here directly, and\n //doing a direct modification of the depMaps array\n //would affect that config.\n this.depMaps = depMaps && depMaps.slice(0);\n\n this.errback = errback;\n\n //Indicate this module has be initialized\n this.inited = true;\n\n this.ignore = options.ignore;\n\n //Could have option to init this module in enabled mode,\n //or could have been previously marked as enabled. However,\n //the dependencies are not known until init is called. So\n //if enabled previously, now trigger dependencies as enabled.\n if (options.enabled || this.enabled) {\n //Enable this module and dependencies.\n //Will call this.check()\n this.enable();\n } else {\n this.check();\n }\n },\n\n defineDep: function (i, depExports) {\n //Because of cycles, defined callback for a given\n //export can be called more than once.\n if (!this.depMatched[i]) {\n this.depMatched[i] = true;\n this.depCount -= 1;\n this.depExports[i] = depExports;\n }\n },\n\n fetch: function () {\n if (this.fetched) {\n return;\n }\n this.fetched = true;\n\n context.startTime = (new Date()).getTime();\n\n var map = this.map;\n\n //If the manager is for a plugin managed resource,\n //ask the plugin to load it now.\n if (this.shim) {\n context.makeRequire(this.map, {\n enableBuildCallback: true\n })(this.shim.deps || [], bind(this, function () {\n return map.prefix ? this.callPlugin() : this.load();\n }));\n } else {\n //Regular dependency.\n return map.prefix ? this.callPlugin() : this.load();\n }\n },\n\n load: function () {\n var url = this.map.url;\n\n //Regular dependency.\n if (!urlFetched[url]) {\n urlFetched[url] = true;\n context.load(this.map.id, url);\n }\n },\n\n /**\n * Checks if the module is ready to define itself, and if so,\n * define it.\n */\n check: function () {\n if (!this.enabled || this.enabling) {\n return;\n }\n\n var err, cjsModule,\n id = this.map.id,\n depExports = this.depExports,\n exports = this.exports,\n factory = this.factory;\n\n if (!this.inited) {\n // Only fetch if not already in the defQueue.\n if (!hasProp(context.defQueueMap, id)) {\n this.fetch();\n }\n } else if (this.error) {\n this.emit('error', this.error);\n } else if (!this.defining) {\n //The factory could trigger another require call\n //that would result in checking this module to\n //define itself again. If already in the process\n //of doing that, skip this work.\n this.defining = true;\n\n if (this.depCount < 1 && !this.defined) {\n if (isFunction(factory)) {\n //If there is an error listener, favor passing\n //to that instead of throwing an error. However,\n //only do it for define()'d modules. require\n //errbacks should not be called for failures in\n //their callbacks (#699). However if a global\n //onError is set, use that.\n if ((this.events.error && this.map.isDefine) ||\n req.onError !== defaultOnError) {\n try {\n exports = context.execCb(id, factory, depExports, exports);\n } catch (e) {\n err = e;\n }\n } else {\n exports = context.execCb(id, factory, depExports, exports);\n }\n\n // Favor return value over exports. If node/cjs in play,\n // then will not have a return value anyway. Favor\n // module.exports assignment over exports object.\n if (this.map.isDefine && exports === undefined) {\n cjsModule = this.module;\n if (cjsModule) {\n exports = cjsModule.exports;\n } else if (this.usingExports) {\n //exports already set the defined value.\n exports = this.exports;\n }\n }\n\n if (err) {\n err.requireMap = this.map;\n err.requireModules = this.map.isDefine ? [this.map.id] : null;\n err.requireType = this.map.isDefine ? 'define' : 'require';\n return onError((this.error = err));\n }\n\n } else {\n //Just a literal value\n exports = factory;\n }\n\n this.exports = exports;\n\n if (this.map.isDefine && !this.ignore) {\n defined[id] = exports;\n\n if (req.onResourceLoad) {\n var resLoadMaps = [];\n each(this.depMaps, function (depMap) {\n resLoadMaps.push(depMap.normalizedMap || depMap);\n });\n req.onResourceLoad(context, this.map, resLoadMaps);\n }\n }\n\n //Clean up\n cleanRegistry(id);\n\n this.defined = true;\n }\n\n //Finished the define stage. Allow calling check again\n //to allow define notifications below in the case of a\n //cycle.\n this.defining = false;\n\n if (this.defined && !this.defineEmitted) {\n this.defineEmitted = true;\n this.emit('defined', this.exports);\n this.defineEmitComplete = true;\n }\n\n }\n },\n\n callPlugin: function () {\n var map = this.map,\n id = map.id,\n //Map already normalized the prefix.\n pluginMap = makeModuleMap(map.prefix);\n\n //Mark this as a dependency for this plugin, so it\n //can be traced for cycles.\n this.depMaps.push(pluginMap);\n\n on(pluginMap, 'defined', bind(this, function (plugin) {\n var load, normalizedMap, normalizedMod,\n bundleId = getOwn(bundlesMap, this.map.id),\n name = this.map.name,\n parentName = this.map.parentMap ? this.map.parentMap.name : null,\n localRequire = context.makeRequire(map.parentMap, {\n enableBuildCallback: true\n });\n\n //If current map is not normalized, wait for that\n //normalized name to load instead of continuing.\n if (this.map.unnormalized) {\n //Normalize the ID if the plugin allows it.\n if (plugin.normalize) {\n name = plugin.normalize(name, function (name) {\n return normalize(name, parentName, true);\n }) || '';\n }\n\n //prefix and name should already be normalized, no need\n //for applying map config again either.\n normalizedMap = makeModuleMap(map.prefix + '!' + name,\n this.map.parentMap,\n true);\n on(normalizedMap,\n 'defined', bind(this, function (value) {\n this.map.normalizedMap = normalizedMap;\n this.init([], function () { return value; }, null, {\n enabled: true,\n ignore: true\n });\n }));\n\n normalizedMod = getOwn(registry, normalizedMap.id);\n if (normalizedMod) {\n //Mark this as a dependency for this plugin, so it\n //can be traced for cycles.\n this.depMaps.push(normalizedMap);\n\n if (this.events.error) {\n normalizedMod.on('error', bind(this, function (err) {\n this.emit('error', err);\n }));\n }\n normalizedMod.enable();\n }\n\n return;\n }\n\n //If a paths config, then just load that file instead to\n //resolve the plugin, as it is built into that paths layer.\n if (bundleId) {\n this.map.url = context.nameToUrl(bundleId);\n this.load();\n return;\n }\n\n load = bind(this, function (value) {\n this.init([], function () { return value; }, null, {\n enabled: true\n });\n });\n\n load.error = bind(this, function (err) {\n this.inited = true;\n this.error = err;\n err.requireModules = [id];\n\n //Remove temp unnormalized modules for this module,\n //since they will never be resolved otherwise now.\n eachProp(registry, function (mod) {\n if (mod.map.id.indexOf(id + '_unnormalized') === 0) {\n cleanRegistry(mod.map.id);\n }\n });\n\n onError(err);\n });\n\n //Allow plugins to load other code without having to know the\n //context or how to 'complete' the load.\n load.fromText = bind(this, function (text, textAlt) {\n /*jslint evil: true */\n var moduleName = map.name,\n moduleMap = makeModuleMap(moduleName),\n hasInteractive = useInteractive;\n\n //As of 2.1.0, support just passing the text, to reinforce\n //fromText only being called once per resource. Still\n //support old style of passing moduleName but discard\n //that moduleName in favor of the internal ref.\n if (textAlt) {\n text = textAlt;\n }\n\n //Turn off interactive script matching for IE for any define\n //calls in the text, then turn it back on at the end.\n if (hasInteractive) {\n useInteractive = false;\n }\n\n //Prime the system by creating a module instance for\n //it.\n getModule(moduleMap);\n\n //Transfer any config to this other module.\n if (hasProp(config.config, id)) {\n config.config[moduleName] = config.config[id];\n }\n\n try {\n req.exec(text);\n } catch (e) {\n return onError(makeError('fromtexteval',\n 'fromText eval for ' + id +\n ' failed: ' + e,\n e,\n [id]));\n }\n\n if (hasInteractive) {\n useInteractive = true;\n }\n\n //Mark this as a dependency for the plugin\n //resource\n this.depMaps.push(moduleMap);\n\n //Support anonymous modules.\n context.completeLoad(moduleName);\n\n //Bind the value of that module to the value for this\n //resource ID.\n localRequire([moduleName], load);\n });\n\n //Use parentName here since the plugin's name is not reliable,\n //could be some weird string with no path that actually wants to\n //reference the parentName's path.\n plugin.load(map.name, localRequire, load, config);\n }));\n\n context.enable(pluginMap, this);\n this.pluginMaps[pluginMap.id] = pluginMap;\n },\n\n enable: function () {\n enabledRegistry[this.map.id] = this;\n this.enabled = true;\n\n //Set flag mentioning that the module is enabling,\n //so that immediate calls to the defined callbacks\n //for dependencies do not trigger inadvertent load\n //with the depCount still being zero.\n this.enabling = true;\n\n //Enable each dependency\n each(this.depMaps, bind(this, function (depMap, i) {\n var id, mod, handler;\n\n if (typeof depMap === 'string') {\n //Dependency needs to be converted to a depMap\n //and wired up to this module.\n depMap = makeModuleMap(depMap,\n (this.map.isDefine ? this.map : this.map.parentMap),\n false,\n !this.skipMap);\n this.depMaps[i] = depMap;\n\n handler = getOwn(handlers, depMap.id);\n\n if (handler) {\n this.depExports[i] = handler(this);\n return;\n }\n\n this.depCount += 1;\n\n on(depMap, 'defined', bind(this, function (depExports) {\n if (this.undefed) {\n return;\n }\n this.defineDep(i, depExports);\n this.check();\n }));\n\n if (this.errback) {\n on(depMap, 'error', bind(this, this.errback));\n } else if (this.events.error) {\n // No direct errback on this module, but something\n // else is listening for errors, so be sure to\n // propagate the error correctly.\n on(depMap, 'error', bind(this, function(err) {\n this.emit('error', err);\n }));\n }\n }\n\n id = depMap.id;\n mod = registry[id];\n\n //Skip special modules like 'require', 'exports', 'module'\n //Also, don't call enable if it is already enabled,\n //important in circular dependency cases.\n if (!hasProp(handlers, id) && mod && !mod.enabled) {\n context.enable(depMap, this);\n }\n }));\n\n //Enable each plugin that is used in\n //a dependency\n eachProp(this.pluginMaps, bind(this, function (pluginMap) {\n var mod = getOwn(registry, pluginMap.id);\n if (mod && !mod.enabled) {\n context.enable(pluginMap, this);\n }\n }));\n\n this.enabling = false;\n\n this.check();\n },\n\n on: function (name, cb) {\n var cbs = this.events[name];\n if (!cbs) {\n cbs = this.events[name] = [];\n }\n cbs.push(cb);\n },\n\n emit: function (name, evt) {\n each(this.events[name], function (cb) {\n cb(evt);\n });\n if (name === 'error') {\n //Now that the error handler was triggered, remove\n //the listeners, since this broken Module instance\n //can stay around for a while in the registry.\n delete this.events[name];\n }\n }\n };\n\n function callGetModule(args) {\n //Skip modules already defined.\n if (!hasProp(defined, args[0])) {\n getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);\n }\n }\n\n function removeListener(node, func, name, ieName) {\n //Favor detachEvent because of IE9\n //issue, see attachEvent/addEventListener comment elsewhere\n //in this file.\n if (node.detachEvent && !isOpera) {\n //Probably IE. If not it will throw an error, which will be\n //useful to know.\n if (ieName) {\n node.detachEvent(ieName, func);\n }\n } else {\n node.removeEventListener(name, func, false);\n }\n }\n\n /**\n * Given an event from a script node, get the requirejs info from it,\n * and then removes the event listeners on the node.\n * @param {Event} evt\n * @returns {Object}\n */\n function getScriptData(evt) {\n //Using currentTarget instead of target for Firefox 2.0's sake. Not\n //all old browsers will be supported, but this one was easy enough\n //to support and still makes sense.\n var node = evt.currentTarget || evt.srcElement;\n\n //Remove the listeners once here.\n removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange');\n removeListener(node, context.onScriptError, 'error');\n\n return {\n node: node,\n id: node && node.getAttribute('data-requiremodule')\n };\n }\n\n function intakeDefines() {\n var args;\n\n //Any defined modules in the global queue, intake them now.\n takeGlobalQueue();\n\n //Make sure any remaining defQueue items get properly processed.\n while (defQueue.length) {\n args = defQueue.shift();\n if (args[0] === null) {\n return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' +\n args[args.length - 1]));\n } else {\n //args are id, deps, factory. Should be normalized by the\n //define() function.\n callGetModule(args);\n }\n }\n context.defQueueMap = {};\n }\n\n context = {\n config: config,\n contextName: contextName,\n registry: registry,\n defined: defined,\n urlFetched: urlFetched,\n defQueue: defQueue,\n defQueueMap: {},\n Module: Module,\n makeModuleMap: makeModuleMap,\n nextTick: req.nextTick,\n onError: onError,\n\n /**\n * Set a configuration for the context.\n * @param {Object} cfg config object to integrate.\n */\n configure: function (cfg) {\n //Make sure the baseUrl ends in a slash.\n if (cfg.baseUrl) {\n if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') {\n cfg.baseUrl += '/';\n }\n }\n\n // Convert old style urlArgs string to a function.\n if (typeof cfg.urlArgs === 'string') {\n var urlArgs = cfg.urlArgs;\n cfg.urlArgs = function(id, url) {\n return (url.indexOf('?') === -1 ? '?' : '&') + urlArgs;\n };\n }\n\n //Save off the paths since they require special processing,\n //they are additive.\n var shim = config.shim,\n objs = {\n paths: true,\n bundles: true,\n config: true,\n map: true\n };\n\n eachProp(cfg, function (value, prop) {\n if (objs[prop]) {\n if (!config[prop]) {\n config[prop] = {};\n }\n mixin(config[prop], value, true, true);\n } else {\n config[prop] = value;\n }\n });\n\n //Reverse map the bundles\n if (cfg.bundles) {\n eachProp(cfg.bundles, function (value, prop) {\n each(value, function (v) {\n if (v !== prop) {\n bundlesMap[v] = prop;\n }\n });\n });\n }\n\n //Merge shim\n if (cfg.shim) {\n eachProp(cfg.shim, function (value, id) {\n //Normalize the structure\n if (isArray(value)) {\n value = {\n deps: value\n };\n }\n if ((value.exports || value.init) && !value.exportsFn) {\n value.exportsFn = context.makeShimExports(value);\n }\n shim[id] = value;\n });\n config.shim = shim;\n }\n\n //Adjust packages if necessary.\n if (cfg.packages) {\n each(cfg.packages, function (pkgObj) {\n var location, name;\n\n pkgObj = typeof pkgObj === 'string' ? {name: pkgObj} : pkgObj;\n\n name = pkgObj.name;\n location = pkgObj.location;\n if (location) {\n config.paths[name] = pkgObj.location;\n }\n\n //Save pointer to main module ID for pkg name.\n //Remove leading dot in main, so main paths are normalized,\n //and remove any trailing .js, since different package\n //envs have different conventions: some use a module name,\n //some use a file name.\n config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main')\n .replace(currDirRegExp, '')\n .replace(jsSuffixRegExp, '');\n });\n }\n\n //If there are any \"waiting to execute\" modules in the registry,\n //update the maps for them, since their info, like URLs to load,\n //may have changed.\n eachProp(registry, function (mod, id) {\n //If module already has init called, since it is too\n //late to modify them, and ignore unnormalized ones\n //since they are transient.\n if (!mod.inited && !mod.map.unnormalized) {\n mod.map = makeModuleMap(id, null, true);\n }\n });\n\n //If a deps array or a config callback is specified, then call\n //require with those args. This is useful when require is defined as a\n //config object before require.js is loaded.\n if (cfg.deps || cfg.callback) {\n context.require(cfg.deps || [], cfg.callback);\n }\n },\n\n makeShimExports: function (value) {\n function fn() {\n var ret;\n if (value.init) {\n ret = value.init.apply(global, arguments);\n }\n return ret || (value.exports && getGlobal(value.exports));\n }\n return fn;\n },\n\n makeRequire: function (relMap, options) {\n options = options || {};\n\n function localRequire(deps, callback, errback) {\n var id, map, requireMod;\n\n if (options.enableBuildCallback && callback && isFunction(callback)) {\n callback.__requireJsBuild = true;\n }\n\n if (typeof deps === 'string') {\n if (isFunction(callback)) {\n //Invalid call\n return onError(makeError('requireargs', 'Invalid require call'), errback);\n }\n\n //If require|exports|module are requested, get the\n //value for them from the special handlers. Caveat:\n //this only works while module is being defined.\n if (relMap && hasProp(handlers, deps)) {\n return handlers[deps](registry[relMap.id]);\n }\n\n //Synchronous access to one module. If require.get is\n //available (as in the Node adapter), prefer that.\n if (req.get) {\n return req.get(context, deps, relMap, localRequire);\n }\n\n //Normalize module name, if it contains . or ..\n map = makeModuleMap(deps, relMap, false, true);\n id = map.id;\n\n if (!hasProp(defined, id)) {\n return onError(makeError('notloaded', 'Module name \"' +\n id +\n '\" has not been loaded yet for context: ' +\n contextName +\n (relMap ? '' : '. Use require([])')));\n }\n return defined[id];\n }\n\n //Grab defines waiting in the global queue.\n intakeDefines();\n\n //Mark all the dependencies as needing to be loaded.\n context.nextTick(function () {\n //Some defines could have been added since the\n //require call, collect them.\n intakeDefines();\n\n requireMod = getModule(makeModuleMap(null, relMap));\n\n //Store if map config should be applied to this require\n //call for dependencies.\n requireMod.skipMap = options.skipMap;\n\n requireMod.init(deps, callback, errback, {\n enabled: true\n });\n\n checkLoaded();\n });\n\n return localRequire;\n }\n\n mixin(localRequire, {\n isBrowser: isBrowser,\n\n /**\n * Converts a module name + .extension into an URL path.\n * *Requires* the use of a module name. It does not support using\n * plain URLs like nameToUrl.\n */\n toUrl: function (moduleNamePlusExt) {\n var ext,\n index = moduleNamePlusExt.lastIndexOf('.'),\n segment = moduleNamePlusExt.split('/')[0],\n isRelative = segment === '.' || segment === '..';\n\n //Have a file extension alias, and it is not the\n //dots from a relative path.\n if (index !== -1 && (!isRelative || index > 1)) {\n ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);\n moduleNamePlusExt = moduleNamePlusExt.substring(0, index);\n }\n\n return context.nameToUrl(normalize(moduleNamePlusExt,\n relMap && relMap.id, true), ext, true);\n },\n\n defined: function (id) {\n return hasProp(defined, makeModuleMap(id, relMap, false, true).id);\n },\n\n specified: function (id) {\n id = makeModuleMap(id, relMap, false, true).id;\n return hasProp(defined, id) || hasProp(registry, id);\n }\n });\n\n //Only allow undef on top level require calls\n if (!relMap) {\n localRequire.undef = function (id) {\n //Bind any waiting define() calls to this context,\n //fix for #408\n takeGlobalQueue();\n\n var map = makeModuleMap(id, relMap, true),\n mod = getOwn(registry, id);\n\n mod.undefed = true;\n removeScript(id);\n\n delete defined[id];\n delete urlFetched[map.url];\n delete undefEvents[id];\n\n //Clean queued defines too. Go backwards\n //in array so that the splices do not\n //mess up the iteration.\n eachReverse(defQueue, function(args, i) {\n if (args[0] === id) {\n defQueue.splice(i, 1);\n }\n });\n delete context.defQueueMap[id];\n\n if (mod) {\n //Hold on to listeners in case the\n //module will be attempted to be reloaded\n //using a different config.\n if (mod.events.defined) {\n undefEvents[id] = mod.events;\n }\n\n cleanRegistry(id);\n }\n };\n }\n\n return localRequire;\n },\n\n /**\n * Called to enable a module if it is still in the registry\n * awaiting enablement. A second arg, parent, the parent module,\n * is passed in for context, when this method is overridden by\n * the optimizer. Not shown here to keep code compact.\n */\n enable: function (depMap) {\n var mod = getOwn(registry, depMap.id);\n if (mod) {\n getModule(depMap).enable();\n }\n },\n\n /**\n * Internal method used by environment adapters to complete a load event.\n * A load event could be a script load or just a load pass from a synchronous\n * load call.\n * @param {String} moduleName the name of the module to potentially complete.\n */\n completeLoad: function (moduleName) {\n var found, args, mod,\n shim = getOwn(config.shim, moduleName) || {},\n shExports = shim.exports;\n\n takeGlobalQueue();\n\n while (defQueue.length) {\n args = defQueue.shift();\n if (args[0] === null) {\n args[0] = moduleName;\n //If already found an anonymous module and bound it\n //to this name, then this is some other anon module\n //waiting for its completeLoad to fire.\n if (found) {\n break;\n }\n found = true;\n } else if (args[0] === moduleName) {\n //Found matching define call for this script!\n found = true;\n }\n\n callGetModule(args);\n }\n context.defQueueMap = {};\n\n //Do this after the cycle of callGetModule in case the result\n //of those calls/init calls changes the registry.\n mod = getOwn(registry, moduleName);\n\n if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) {\n if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {\n if (hasPathFallback(moduleName)) {\n return;\n } else {\n return onError(makeError('nodefine',\n 'No define call for ' + moduleName,\n null,\n [moduleName]));\n }\n } else {\n //A script that does not call define(), so just simulate\n //the call for it.\n callGetModule([moduleName, (shim.deps || []), shim.exportsFn]);\n }\n }\n\n checkLoaded();\n },\n\n /**\n * Converts a module name to a file path. Supports cases where\n * moduleName may actually be just an URL.\n * Note that it **does not** call normalize on the moduleName,\n * it is assumed to have already been normalized. This is an\n * internal API, not a public one. Use toUrl for the public API.\n */\n nameToUrl: function (moduleName, ext, skipExt) {\n var paths, syms, i, parentModule, url,\n parentPath, bundleId,\n pkgMain = getOwn(config.pkgs, moduleName);\n\n if (pkgMain) {\n moduleName = pkgMain;\n }\n\n bundleId = getOwn(bundlesMap, moduleName);\n\n if (bundleId) {\n return context.nameToUrl(bundleId, ext, skipExt);\n }\n\n //If a colon is in the URL, it indicates a protocol is used and it is just\n //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)\n //or ends with .js, then assume the user meant to use an url and not a module id.\n //The slash is important for protocol-less URLs as well as full paths.\n if (req.jsExtRegExp.test(moduleName)) {\n //Just a plain path, not module name lookup, so just return it.\n //Add extension if it is included. This is a bit wonky, only non-.js things pass\n //an extension, this method probably needs to be reworked.\n url = moduleName + (ext || '');\n } else {\n //A module that needs to be converted to a path.\n paths = config.paths;\n\n syms = moduleName.split('/');\n //For each module name segment, see if there is a path\n //registered for it. Start with most specific name\n //and work up from it.\n for (i = syms.length; i > 0; i -= 1) {\n parentModule = syms.slice(0, i).join('/');\n\n parentPath = getOwn(paths, parentModule);\n if (parentPath) {\n //If an array, it means there are a few choices,\n //Choose the one that is desired\n if (isArray(parentPath)) {\n parentPath = parentPath[0];\n }\n syms.splice(0, i, parentPath);\n break;\n }\n }\n\n //Join the path parts together, then figure out if baseUrl is needed.\n url = syms.join('/');\n url += (ext || (/^data\\:|^blob\\:|\\?/.test(url) || skipExt ? '' : '.js'));\n url = (url.charAt(0) === '/' || url.match(/^[\\w\\+\\.\\-]+:/) ? '' : config.baseUrl) + url;\n }\n\n return config.urlArgs && !/^blob\\:/.test(url) ?\n url + config.urlArgs(moduleName, url) : url;\n },\n\n //Delegates to req.load. Broken out as a separate function to\n //allow overriding in the optimizer.\n load: function (id, url) {\n req.load(context, id, url);\n },\n\n /**\n * Executes a module callback function. Broken out as a separate function\n * solely to allow the build system to sequence the files in the built\n * layer in the right sequence.\n *\n * @private\n */\n execCb: function (name, callback, args, exports) {\n return callback.apply(exports, args);\n },\n\n /**\n * callback for script loads, used to check status of loading.\n *\n * @param {Event} evt the event from the browser for the script\n * that was loaded.\n */\n onScriptLoad: function (evt) {\n //Using currentTarget instead of target for Firefox 2.0's sake. Not\n //all old browsers will be supported, but this one was easy enough\n //to support and still makes sense.\n if (evt.type === 'load' ||\n (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {\n //Reset interactive script so a script node is not held onto for\n //to long.\n interactiveScript = null;\n\n //Pull out the name of the module and the context.\n var data = getScriptData(evt);\n context.completeLoad(data.id);\n }\n },\n\n /**\n * Callback for script errors.\n */\n onScriptError: function (evt) {\n var data = getScriptData(evt);\n if (!hasPathFallback(data.id)) {\n var parents = [];\n eachProp(registry, function(value, key) {\n if (key.indexOf('_@r') !== 0) {\n each(value.depMaps, function(depMap) {\n if (depMap.id === data.id) {\n parents.push(key);\n return true;\n }\n });\n }\n });\n return onError(makeError('scripterror', 'Script error for \"' + data.id +\n (parents.length ?\n '\", needed by: ' + parents.join(', ') :\n '\"'), evt, [data.id]));\n }\n }\n };\n\n context.require = context.makeRequire();\n return context;\n }\n\n /**\n * Main entry point.\n *\n * If the only argument to require is a string, then the module that\n * is represented by that string is fetched for the appropriate context.\n *\n * If the first argument is an array, then it will be treated as an array\n * of dependency string names to fetch. An optional function callback can\n * be specified to execute when all of those dependencies are available.\n *\n * Make a local req variable to help Caja compliance (it assumes things\n * on a require that are not standardized), and to give a short\n * name for minification/local scope use.\n */\n req = requirejs = function (deps, callback, errback, optional) {\n\n //Find the right context, use default\n var context, config,\n contextName = defContextName;\n\n // Determine if have config object in the call.\n if (!isArray(deps) && typeof deps !== 'string') {\n // deps is a config object\n config = deps;\n if (isArray(callback)) {\n // Adjust args if there are dependencies\n deps = callback;\n callback = errback;\n errback = optional;\n } else {\n deps = [];\n }\n }\n\n if (config && config.context) {\n contextName = config.context;\n }\n\n context = getOwn(contexts, contextName);\n if (!context) {\n context = contexts[contextName] = req.s.newContext(contextName);\n }\n\n if (config) {\n context.configure(config);\n }\n\n return context.require(deps, callback, errback);\n };\n\n /**\n * Support require.config() to make it easier to cooperate with other\n * AMD loaders on globally agreed names.\n */\n req.config = function (config) {\n return req(config);\n };\n\n /**\n * Execute something after the current tick\n * of the event loop. Override for other envs\n * that have a better solution than setTimeout.\n * @param {Function} fn function to execute later.\n */\n req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) {\n setTimeout(fn, 4);\n } : function (fn) { fn(); };\n\n /**\n * Export require as a global, but only if it does not already exist.\n */\n if (!require) {\n require = req;\n }\n\n req.version = version;\n\n //Used to filter out dependencies that are already paths.\n req.jsExtRegExp = /^\\/|:|\\?|\\.js$/;\n req.isBrowser = isBrowser;\n s = req.s = {\n contexts: contexts,\n newContext: newContext\n };\n\n //Create default context.\n req({});\n\n //Exports some context-sensitive methods on global require.\n each([\n 'toUrl',\n 'undef',\n 'defined',\n 'specified'\n ], function (prop) {\n //Reference from contexts instead of early binding to default context,\n //so that during builds, the latest instance of the default context\n //with its config gets used.\n req[prop] = function () {\n var ctx = contexts[defContextName];\n return ctx.require[prop].apply(ctx, arguments);\n };\n });\n\n if (isBrowser) {\n head = s.head = document.getElementsByTagName('head')[0];\n //If BASE tag is in play, using appendChild is a problem for IE6.\n //When that browser dies, this can be removed. Details in this jQuery bug:\n //http://dev.jquery.com/ticket/2709\n baseElement = document.getElementsByTagName('base')[0];\n if (baseElement) {\n head = s.head = baseElement.parentNode;\n }\n }\n\n /**\n * Any errors that require explicitly generates will be passed to this\n * function. Intercept/override it if you want custom error handling.\n * @param {Error} err the error object.\n */\n req.onError = defaultOnError;\n\n /**\n * Creates the node for the load command. Only used in browser envs.\n */\n req.createNode = function (config, moduleName, url) {\n var node = config.xhtml ?\n document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :\n document.createElement('script');\n node.type = config.scriptType || 'text/javascript';\n node.charset = 'utf-8';\n node.async = true;\n return node;\n };\n\n /**\n * Does the request to load a module for the browser case.\n * Make this a separate function to allow other environments\n * to override it.\n *\n * @param {Object} context the require context to find state.\n * @param {String} moduleName the name of the module.\n * @param {Object} url the URL to the module.\n */\n req.load = function (context, moduleName, url) {\n var config = (context && context.config) || {},\n node;\n if (isBrowser) {\n //In the browser so use a script tag\n node = req.createNode(config, moduleName, url);\n\n node.setAttribute('data-requirecontext', context.contextName);\n node.setAttribute('data-requiremodule', moduleName);\n\n //Set up load listener. Test attachEvent first because IE9 has\n //a subtle issue in its addEventListener and script onload firings\n //that do not match the behavior of all other browsers with\n //addEventListener support, which fire the onload event for a\n //script right after the script execution. See:\n //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution\n //UNFORTUNATELY Opera implements attachEvent but does not follow the script\n //script execution mode.\n if (node.attachEvent &&\n //Check if node.attachEvent is artificially added by custom script or\n //natively supported by browser\n //read https://github.com/requirejs/requirejs/issues/187\n //if we can NOT find [native code] then it must NOT natively supported.\n //in IE8, node.attachEvent does not have toString()\n //Note the test for \"[native code\" with no closing brace, see:\n //https://github.com/requirejs/requirejs/issues/273\n !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&\n !isOpera) {\n //Probably IE. IE (at least 6-8) do not fire\n //script onload right after executing the script, so\n //we cannot tie the anonymous define call to a name.\n //However, IE reports the script as being in 'interactive'\n //readyState at the time of the define call.\n useInteractive = true;\n\n node.attachEvent('onreadystatechange', context.onScriptLoad);\n //It would be great to add an error handler here to catch\n //404s in IE9+. However, onreadystatechange will fire before\n //the error handler, so that does not help. If addEventListener\n //is used, then IE will fire error before load, but we cannot\n //use that pathway given the connect.microsoft.com issue\n //mentioned above about not doing the 'script execute,\n //then fire the script load event listener before execute\n //next script' that other browsers do.\n //Best hope: IE10 fixes the issues,\n //and then destroys all installs of IE 6-9.\n //node.attachEvent('onerror', context.onScriptError);\n } else {\n node.addEventListener('load', context.onScriptLoad, false);\n node.addEventListener('error', context.onScriptError, false);\n }\n node.src = url;\n\n //Calling onNodeCreated after all properties on the node have been\n //set, but before it is placed in the DOM.\n if (config.onNodeCreated) {\n config.onNodeCreated(node, config, moduleName, url);\n }\n\n //For some cache cases in IE 6-8, the script executes before the end\n //of the appendChild execution, so to tie an anonymous define\n //call to the module name (which is stored on the node), hold on\n //to a reference to this node, but clear after the DOM insertion.\n currentlyAddingScript = node;\n if (baseElement) {\n head.insertBefore(node, baseElement);\n } else {\n head.appendChild(node);\n }\n currentlyAddingScript = null;\n\n return node;\n } else if (isWebWorker) {\n try {\n //In a web worker, use importScripts. This is not a very\n //efficient use of importScripts, importScripts will block until\n //its script is downloaded and evaluated. However, if web workers\n //are in play, the expectation is that a build has been done so\n //that only one script needs to be loaded anyway. This may need\n //to be reevaluated if other use cases become common.\n\n // Post a task to the event loop to work around a bug in WebKit\n // where the worker gets garbage-collected after calling\n // importScripts(): https://webkit.org/b/153317\n setTimeout(function() {}, 0);\n importScripts(url);\n\n //Account for anonymous modules\n context.completeLoad(moduleName);\n } catch (e) {\n context.onError(makeError('importscripts',\n 'importScripts failed for ' +\n moduleName + ' at ' + url,\n e,\n [moduleName]));\n }\n }\n };\n\n function getInteractiveScript() {\n if (interactiveScript && interactiveScript.readyState === 'interactive') {\n return interactiveScript;\n }\n\n eachReverse(scripts(), function (script) {\n if (script.readyState === 'interactive') {\n return (interactiveScript = script);\n }\n });\n return interactiveScript;\n }\n\n //Look for a data-main script attribute, which could also adjust the baseUrl.\n if (isBrowser && !cfg.skipDataMain) {\n //Figure out baseUrl. Get it from the script tag with require.js in it.\n eachReverse(scripts(), function (script) {\n //Set the 'head' where we can append children by\n //using the script's parent.\n if (!head) {\n head = script.parentNode;\n }\n\n //Look for a data-main attribute to set main script for the page\n //to load. If it is there, the path to data main becomes the\n //baseUrl, if it is not already set.\n dataMain = script.getAttribute('data-main');\n if (dataMain) {\n //Preserve dataMain in case it is a path (i.e. contains '?')\n mainScript = dataMain;\n\n //Set final baseUrl if there is not already an explicit one,\n //but only do so if the data-main value is not a loader plugin\n //module ID.\n if (!cfg.baseUrl && mainScript.indexOf('!') === -1) {\n //Pull off the directory of data-main for use as the\n //baseUrl.\n src = mainScript.split('/');\n mainScript = src.pop();\n subPath = src.length ? src.join('/') + '/' : './';\n\n cfg.baseUrl = subPath;\n }\n\n //Strip off any trailing .js since mainScript is now\n //like a module name.\n mainScript = mainScript.replace(jsSuffixRegExp, '');\n\n //If mainScript is still a path, fall back to dataMain\n if (req.jsExtRegExp.test(mainScript)) {\n mainScript = dataMain;\n }\n\n //Put the data-main script in the files to load.\n cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];\n\n return true;\n }\n });\n }\n\n /**\n * The function that handles definitions of modules. Differs from\n * require() in that a string for the module should be the first argument,\n * and the function to execute after dependencies are loaded should\n * return a value to define the module corresponding to the first argument's\n * name.\n */\n define = function (name, deps, callback) {\n var node, context;\n\n //Allow for anonymous modules\n if (typeof name !== 'string') {\n //Adjust args appropriately\n callback = deps;\n deps = name;\n name = null;\n }\n\n //This module may not have dependencies\n if (!isArray(deps)) {\n callback = deps;\n deps = null;\n }\n\n //If no name, and callback is a function, then figure out if it a\n //CommonJS thing with dependencies.\n if (!deps && isFunction(callback)) {\n deps = [];\n //Remove comments from the callback string,\n //look for require calls, and pull them into the dependencies,\n //but only if there are function args.\n if (callback.length) {\n callback\n .toString()\n .replace(commentRegExp, commentReplace)\n .replace(cjsRequireRegExp, function (match, dep) {\n deps.push(dep);\n });\n\n //May be a CommonJS thing even without require calls, but still\n //could use exports, and module. Avoid doing exports and module\n //work though if it just needs require.\n //REQUIRES the function to expect the CommonJS variables in the\n //order listed below.\n deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);\n }\n }\n\n //If in IE 6-8 and hit an anonymous define() call, do the interactive\n //work.\n if (useInteractive) {\n node = currentlyAddingScript || getInteractiveScript();\n if (node) {\n if (!name) {\n name = node.getAttribute('data-requiremodule');\n }\n context = contexts[node.getAttribute('data-requirecontext')];\n }\n }\n\n //Always save off evaluating the def call until the script onload handler.\n //This allows multiple modules to be in a file without prematurely\n //tracing dependencies, and allows for anonymous module support,\n //where the module name is not known until the script onload event\n //occurs. If no context, use the global queue, and get it processed\n //in the onscript load callback.\n if (context) {\n context.defQueue.push([name, deps, callback]);\n context.defQueueMap[name] = true;\n } else {\n globalDefQueue.push([name, deps, callback]);\n }\n };\n\n define.amd = {\n jQuery: true\n };\n\n /**\n * Executes the text. Normally just uses eval, but can be modified\n * to use a better, environment-specific call. Only used for transpiling\n * loader plugins, not for plain JS modules.\n * @param {String} text the text to execute/evaluate.\n */\n req.exec = function (text) {\n /*jslint evil: true */\n return eval(text);\n };\n\n //Set up with config info.\n req(cfg);\n}(this, (typeof setTimeout === 'undefined' ? undefined : setTimeout)));\n\ndefine(\"requireLib\", function(){});\n\n",
|
|
33
|
-
"!function(r,n){\"object\"==typeof exports&&\"undefined\"!=typeof module?n(exports):\"function\"==typeof define&&define.amd?define('vendor/uuid',[\"exports\"],n):n((r=r||self).uuid={})}(this,(function(r){\"use strict\";var n=\"undefined\"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||\"undefined\"!=typeof msCrypto&&\"function\"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto),e=new Uint8Array(16);function t(){if(!n)throw new Error(\"crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported\");return n(e)}for(var o,a,u=[],f=0;f<256;++f)u[f]=(f+256).toString(16).substr(1);function c(r,n){var e=n||0,t=u;return[t[r[e++]],t[r[e++]],t[r[e++]],t[r[e++]],\"-\",t[r[e++]],t[r[e++]],\"-\",t[r[e++]],t[r[e++]],\"-\",t[r[e++]],t[r[e++]],\"-\",t[r[e++]],t[r[e++]],t[r[e++]],t[r[e++]],t[r[e++]],t[r[e++]]].join(\"\")}var i=0,s=0;function v(r,n,e){var t=function(r,t,o,a){var u=o&&a||0;if(\"string\"==typeof r&&(r=function(r){r=unescape(encodeURIComponent(r));for(var n=new Array(r.length),e=0;e<r.length;e++)n[e]=r.charCodeAt(e);return n}(r)),\"string\"==typeof t&&(t=function(r){var n=[];return r.replace(/[a-fA-F0-9]{2}/g,(function(r){n.push(parseInt(r,16))})),n}(t)),!Array.isArray(r))throw TypeError(\"value must be an array of bytes\");if(!Array.isArray(t)||16!==t.length)throw TypeError(\"namespace must be uuid string or an Array of 16 byte values\");var f=e(t.concat(r));if(f[6]=15&f[6]|n,f[8]=63&f[8]|128,o)for(var i=0;i<16;++i)o[u+i]=f[i];return o||c(f)};try{t.name=r}catch(r){}return t.DNS=\"6ba7b810-9dad-11d1-80b4-00c04fd430c8\",t.URL=\"6ba7b811-9dad-11d1-80b4-00c04fd430c8\",t}function d(r,n){var e=(65535&r)+(65535&n);return(r>>16)+(n>>16)+(e>>16)<<16|65535&e}function l(r,n,e,t,o,a){return d((u=d(d(n,r),d(t,a)))<<(f=o)|u>>>32-f,e);var u,f}function p(r,n,e,t,o,a,u){return l(n&e|~n&t,r,n,o,a,u)}function y(r,n,e,t,o,a,u){return l(n&t|e&~t,r,n,o,a,u)}function h(r,n,e,t,o,a,u){return l(n^e^t,r,n,o,a,u)}function g(r,n,e,t,o,a,u){return l(e^(n|~t),r,n,o,a,u)}var m=v(\"v3\",48,(function(r){if(\"string\"==typeof r){var n=unescape(encodeURIComponent(r));r=new Array(n.length);for(var e=0;e<n.length;e++)r[e]=n.charCodeAt(e)}return function(r){var n,e,t,o=[],a=32*r.length;for(n=0;n<a;n+=8)e=r[n>>5]>>>n%32&255,t=parseInt(\"0123456789abcdef\".charAt(e>>>4&15)+\"0123456789abcdef\".charAt(15&e),16),o.push(t);return o}(function(r,n){var e,t,o,a,u;r[n>>5]|=128<<n%32,r[14+(n+64>>>9<<4)]=n;var f=1732584193,c=-271733879,i=-1732584194,s=271733878;for(e=0;e<r.length;e+=16)t=f,o=c,a=i,u=s,f=p(f,c,i,s,r[e],7,-680876936),s=p(s,f,c,i,r[e+1],12,-389564586),i=p(i,s,f,c,r[e+2],17,606105819),c=p(c,i,s,f,r[e+3],22,-1044525330),f=p(f,c,i,s,r[e+4],7,-176418897),s=p(s,f,c,i,r[e+5],12,1200080426),i=p(i,s,f,c,r[e+6],17,-1473231341),c=p(c,i,s,f,r[e+7],22,-45705983),f=p(f,c,i,s,r[e+8],7,1770035416),s=p(s,f,c,i,r[e+9],12,-1958414417),i=p(i,s,f,c,r[e+10],17,-42063),c=p(c,i,s,f,r[e+11],22,-1990404162),f=p(f,c,i,s,r[e+12],7,1804603682),s=p(s,f,c,i,r[e+13],12,-40341101),i=p(i,s,f,c,r[e+14],17,-1502002290),c=p(c,i,s,f,r[e+15],22,1236535329),f=y(f,c,i,s,r[e+1],5,-165796510),s=y(s,f,c,i,r[e+6],9,-1069501632),i=y(i,s,f,c,r[e+11],14,643717713),c=y(c,i,s,f,r[e],20,-373897302),f=y(f,c,i,s,r[e+5],5,-701558691),s=y(s,f,c,i,r[e+10],9,38016083),i=y(i,s,f,c,r[e+15],14,-660478335),c=y(c,i,s,f,r[e+4],20,-405537848),f=y(f,c,i,s,r[e+9],5,568446438),s=y(s,f,c,i,r[e+14],9,-1019803690),i=y(i,s,f,c,r[e+3],14,-187363961),c=y(c,i,s,f,r[e+8],20,1163531501),f=y(f,c,i,s,r[e+13],5,-1444681467),s=y(s,f,c,i,r[e+2],9,-51403784),i=y(i,s,f,c,r[e+7],14,1735328473),c=y(c,i,s,f,r[e+12],20,-1926607734),f=h(f,c,i,s,r[e+5],4,-378558),s=h(s,f,c,i,r[e+8],11,-2022574463),i=h(i,s,f,c,r[e+11],16,1839030562),c=h(c,i,s,f,r[e+14],23,-35309556),f=h(f,c,i,s,r[e+1],4,-1530992060),s=h(s,f,c,i,r[e+4],11,1272893353),i=h(i,s,f,c,r[e+7],16,-155497632),c=h(c,i,s,f,r[e+10],23,-1094730640),f=h(f,c,i,s,r[e+13],4,681279174),s=h(s,f,c,i,r[e],11,-358537222),i=h(i,s,f,c,r[e+3],16,-722521979),c=h(c,i,s,f,r[e+6],23,76029189),f=h(f,c,i,s,r[e+9],4,-640364487),s=h(s,f,c,i,r[e+12],11,-421815835),i=h(i,s,f,c,r[e+15],16,530742520),c=h(c,i,s,f,r[e+2],23,-995338651),f=g(f,c,i,s,r[e],6,-198630844),s=g(s,f,c,i,r[e+7],10,1126891415),i=g(i,s,f,c,r[e+14],15,-1416354905),c=g(c,i,s,f,r[e+5],21,-57434055),f=g(f,c,i,s,r[e+12],6,1700485571),s=g(s,f,c,i,r[e+3],10,-1894986606),i=g(i,s,f,c,r[e+10],15,-1051523),c=g(c,i,s,f,r[e+1],21,-2054922799),f=g(f,c,i,s,r[e+8],6,1873313359),s=g(s,f,c,i,r[e+15],10,-30611744),i=g(i,s,f,c,r[e+6],15,-1560198380),c=g(c,i,s,f,r[e+13],21,1309151649),f=g(f,c,i,s,r[e+4],6,-145523070),s=g(s,f,c,i,r[e+11],10,-1120210379),i=g(i,s,f,c,r[e+2],15,718787259),c=g(c,i,s,f,r[e+9],21,-343485551),f=d(f,t),c=d(c,o),i=d(i,a),s=d(s,u);return[f,c,i,s]}(function(r){var n,e=[];for(e[(r.length>>2)-1]=void 0,n=0;n<e.length;n+=1)e[n]=0;var t=8*r.length;for(n=0;n<t;n+=8)e[n>>5]|=(255&r[n/8])<<n%32;return e}(r),8*r.length))}));function b(r,n,e,t){switch(r){case 0:return n&e^~n&t;case 1:return n^e^t;case 2:return n&e^n&t^e&t;case 3:return n^e^t}}function A(r,n){return r<<n|r>>>32-n}var w=v(\"v5\",80,(function(r){var n=[1518500249,1859775393,2400959708,3395469782],e=[1732584193,4023233417,2562383102,271733878,3285377520];if(\"string\"==typeof r){var t=unescape(encodeURIComponent(r));r=new Array(t.length);for(var o=0;o<t.length;o++)r[o]=t.charCodeAt(o)}r.push(128);var a=r.length/4+2,u=Math.ceil(a/16),f=new Array(u);for(o=0;o<u;o++){f[o]=new Array(16);for(var c=0;c<16;c++)f[o][c]=r[64*o+4*c]<<24|r[64*o+4*c+1]<<16|r[64*o+4*c+2]<<8|r[64*o+4*c+3]}for(f[u-1][14]=8*(r.length-1)/Math.pow(2,32),f[u-1][14]=Math.floor(f[u-1][14]),f[u-1][15]=8*(r.length-1)&4294967295,o=0;o<u;o++){for(var i=new Array(80),s=0;s<16;s++)i[s]=f[o][s];for(s=16;s<80;s++)i[s]=A(i[s-3]^i[s-8]^i[s-14]^i[s-16],1);var v=e[0],d=e[1],l=e[2],p=e[3],y=e[4];for(s=0;s<80;s++){var h=Math.floor(s/20),g=A(v,5)+b(h,d,l,p)+y+n[h]+i[s]>>>0;y=p,p=l,l=A(d,30)>>>0,d=v,v=g}e[0]=e[0]+v>>>0,e[1]=e[1]+d>>>0,e[2]=e[2]+l>>>0,e[3]=e[3]+p>>>0,e[4]=e[4]+y>>>0}return[e[0]>>24&255,e[0]>>16&255,e[0]>>8&255,255&e[0],e[1]>>24&255,e[1]>>16&255,e[1]>>8&255,255&e[1],e[2]>>24&255,e[2]>>16&255,e[2]>>8&255,255&e[2],e[3]>>24&255,e[3]>>16&255,e[3]>>8&255,255&e[3],e[4]>>24&255,e[4]>>16&255,e[4]>>8&255,255&e[4]]}));r.v1=function(r,n,e){var u=n&&e||0,f=n||[],v=(r=r||{}).node||o,d=void 0!==r.clockseq?r.clockseq:a;if(null==v||null==d){var l=r.random||(r.rng||t)();null==v&&(v=o=[1|l[0],l[1],l[2],l[3],l[4],l[5]]),null==d&&(d=a=16383&(l[6]<<8|l[7]))}var p=void 0!==r.msecs?r.msecs:(new Date).getTime(),y=void 0!==r.nsecs?r.nsecs:s+1,h=p-i+(y-s)/1e4;if(h<0&&void 0===r.clockseq&&(d=d+1&16383),(h<0||p>i)&&void 0===r.nsecs&&(y=0),y>=1e4)throw new Error(\"uuid.v1(): Can't create more than 10M uuids/sec\");i=p,s=y,a=d;var g=(1e4*(268435455&(p+=122192928e5))+y)%4294967296;f[u++]=g>>>24&255,f[u++]=g>>>16&255,f[u++]=g>>>8&255,f[u++]=255&g;var m=p/4294967296*1e4&268435455;f[u++]=m>>>8&255,f[u++]=255&m,f[u++]=m>>>24&15|16,f[u++]=m>>>16&255,f[u++]=d>>>8|128,f[u++]=255&d;for(var b=0;b<6;++b)f[u+b]=v[b];return n||c(f)},r.v3=m,r.v4=function(r,n,e){var o=n&&e||0;\"string\"==typeof r&&(n=\"binary\"===r?new Array(16):null,r=null);var a=(r=r||{}).random||(r.rng||t)();if(a[6]=15&a[6]|64,a[8]=63&a[8]|128,n)for(var u=0;u<16;++u)n[o+u]=a[u];return n||c(a)},r.v5=w,Object.defineProperty(r,\"__esModule\",{value:!0})}));\n",
|
|
34
|
-
"'use strict';\nfunction Merge() {\n\n var newTarget = []\n //, keyComparison = 'id' // use for collections merging [{ id: 'val1' }, { id: 'val2' }, {id: 'val3' }, ...]\n ;\n \n \n /**\n *\n * @param {object} target - Target object\n * @param {object} source - Source object\n * @param {boolean} [override] - Override when copying\n *\n * @returns {object} [result]\n * */\n var browse = function (target, source) {\n \n if ( typeof(target) == 'undefined' ) {\n target = ( typeof(source) != 'undefined' && Array.isArray(source)) ? [] : {}\n }\n\n var override = false;\n if (( typeof(arguments[arguments.length-1]) == 'boolean' )) {\n override = arguments[arguments.length-1]\n }\n\n var i = 1;\n var length = arguments.length;\n\n var options, /**name,*/ src, copy, copyIsArray, clone;\n\n\n\n // Handle case when target is a string or something (possible in deep copy)\n if (typeof(target) !== 'object' && typeof(target) !== 'function') {\n if (override) {\n if (typeof(arguments[2]) == 'undefined') {\n target = arguments[1]\n } else {\n target = arguments[2]\n }\n } else {\n if (typeof(arguments[0]) == 'undefined') {\n target = arguments[1]\n } else {\n target = arguments[0]\n }\n }\n\n } else {\n for (; i < length; ++i) {\n // Only deal with non-null/undefined values\n if ( typeof(arguments[i]) != 'boolean' && ( options = arguments[i]) != null) {\n if ( typeof(options) != 'object') {\n target = options;\n break;\n }\n\n // both target & options are arrays\n if ( Array.isArray(options) && Array.isArray(target) ) {\n target = mergeArray(options, target, override);\n } else {\n // Merge the base object\n for (var name in options) {\n if (!target) {\n target = { name: null }\n }\n \n src = target[ name ];\n copy = options[ name ];\n\n\n // Prevent never-ending loop\n if (target === copy) {\n continue\n }\n\n // Recurse if we're merging plain objects or arrays\n if (\n copy\n && (\n isObject(copy) ||\n ( copyIsArray = Array.isArray(copy) )\n )\n ) {\n\n var createMode = false;\n if (copyIsArray) {\n copyIsArray = false;\n //clone = src && Array.isArray(src) ? src : [];\n if ( src && Array.isArray(src) ) {\n clone = src || []\n } else if ( isObject(src) ) {\n clone = src || {};\n target[ name ] = clone;\n continue\n } else {\n clone = []\n }\n\n newTarget = clone;\n clone = mergeArray(copy, clone, override);\n target[ name ] = clone;\n continue\n\n } else {\n\n clone = src && isObject(src) ? src : null;\n\n if (!clone) {\n createMode = true;\n clone = {};\n // copy props\n for (var prop in copy) {\n clone[prop] = copy[prop]\n }\n }\n }\n\n\n\n //[propose] Supposed to go deep... deep... deep...\n if ( !override ) {\n // add those in copy not in clone (target)\n\n for (var prop in copy) {\n if (typeof(clone[ prop ]) == 'undefined') {\n if ( Array.isArray(copy[ prop ]) && Array.isArray(clone[ prop ]) ) {\n clone[ prop ] = mergeArray(copy[ prop ], clone[ prop ], override);\n } else {\n clone[ prop ] = copy[ prop ] // don't override existing\n }\n } else if ( Array.isArray(copy[ prop ]) && Array.isArray(clone[ prop ]) ) {\n clone[ prop ] = mergeArray(copy[ prop ], clone[ prop ], override);\n }\n }\n\n\n\n\n // Never move original objects, clone them\n if (typeof(src) != 'boolean' && !createMode ) {//if property is not boolean\n\n // Attention: might lead to a `Maximum call stack size exceeded` Error message\n target[ name ] = browse(clone, copy, override);\n\n // this does not work ... target is returned before the end of process.nextTick !!!\n // process.nextTick(function onBrowse() {\n // target[name] = browse(clone, copy, override)\n // });\n\n // nextTickCalled = true;\n // process.nextTick(function onBrowse() {\n // nextTickCalled = false;\n // //target[ name ] = browse(clone, copy, override);\n // return browse(clone, copy, override);\n // });\n\n\n } else if (createMode) {\n target[ name ] = clone;\n }\n\n } else {\n\n for (var prop in copy) {\n if ( typeof(copy[ prop ]) != 'undefined' ) {\n //clone[prop] = copy[prop]\n if ( Array.isArray(copy[ prop ]) && Array.isArray(clone[ prop ]) ) {\n clone[ prop ] = mergeArray(copy[ prop ], clone[ prop ], override);\n } else {\n clone[ prop ] = copy[ prop ] // don't override existing\n }\n } else if ( Array.isArray(copy[ prop ]) && Array.isArray(clone[ prop ]) ) {\n clone[ prop ] = mergeArray(copy[ prop ], clone[ prop ], override);\n }\n }\n\n target[ name ] = clone;\n }\n\n } else if (copy !== undefined) {\n //[propose]Don't override existing if prop defined or override @ false\n if (\n typeof(src) != 'undefined'\n && src != null\n && src !== copy && !override\n ) {\n target[ name ] = src;\n } else {\n target[ name ] = copy;\n }\n\n }\n }\n }\n }\n\n }\n\n }\n\n newTarget = [];\n \n \n \n // return { \n // 'setKeyComparison' : function(key) {\n // mergeArray.key = key;\n // return target;\n // }\n // } || target\n \n return target;\n\n };\n\n // Will not merge functions items: this is normal\n // Merging arrays is OK, but merging collections is still experimental \n var mergeArray = function(options, target, override) {\n newTarget = [];\n \n \n var newTargetIds = []\n , keyComparison = browse.getKeyComparison()\n , a = null\n , aLen = null\n , i = 0\n ;\n\n if (/^true$/i.test(override)) {\n // if collection, comparison will be done uppon the `id` attribute by default unless you call .setKeyComparison('someField')\n if (\n typeof(options[0]) == 'object'\n && typeof(options[0][keyComparison]) != 'undefined'\n && typeof(target[0]) == 'object' \n && typeof(target[0][keyComparison]) != 'undefined'\n ) {\n\n newTarget = (Array.isArray(target)) ? Array.from(target) : JSON.clone(target);\n for (var nt = 0, ntLen = newTarget.length; nt < ntLen; ++nt) {\n newTargetIds.push(newTarget[nt][keyComparison]);\n }\n \n var _options = JSON.clone(options); \n var index = 0;\n a = 0;\n aLen = _options.length;\n for (var n = next || 0, nLen = target.length; n < nLen; ++n) {\n \n // if (newTargetIds.indexOf(target[n][keyComparison]) == -1) {\n // newTargetIds.push(target[n][keyComparison]);\n \n // //newTarget.push(target[n]);\n // //++index;\n // }\n \n label:\n for (a = a || 0; a < aLen; ++a) {\n \n if (_options[a][keyComparison] === target[n][keyComparison] ) {\n\n if (newTargetIds.indexOf(_options[a][keyComparison]) > -1) {\n \n newTarget[index] = _options[a];\n ++index;\n \n } else if (newTargetIds.indexOf(_options[a][keyComparison]) == -1) {\n\n newTargetIds.push(_options[a][keyComparison]); \n //newTarget.push(_options[a]);\n newTarget[index] = _options[a];\n ++index;\n }\n\n break label;\n \n } else if (newTargetIds.indexOf(_options[a][keyComparison]) == -1) { \n \n newTargetIds.push(_options[a][keyComparison]);\n newTarget.push(_options[a]);\n }\n } // EO For\n }\n\n newTargetIds = [];\n\n return newTarget;\n\n } else { // normal case `arrays` or merging from a blank collection\n if (\n Array.isArray(options) && options.length == 0\n ||\n typeof(options) == 'undefined'\n ) {\n // means that we are trying to replace with an empty array/collection\n // this does not make any sense, so we just return the target as if the merge had no effect\n // DO NOT CHANGE THIS, it affects gina merging config\n return target;\n }\n return options;\n }\n }\n\n if ( options.length == 0 && target.length > 0 ) {\n newTarget = target;\n return newTarget;\n }\n\n if ( target.length == 0 && options.length > 0) {\n a = 0;\n for (; a < options.length; ++a ) {\n target.push(options[a]);\n }\n }\n\n if (newTarget.length == 0 && target.length > 0) { \n // ok, but don't merge objects\n a = 0;\n for (; a < target.length; ++a ) {\n if ( typeof(target[a]) != 'object' && newTarget.indexOf(target[a]) == -1 ) {\n newTarget.push(target[a]);\n }\n }\n }\n \n if ( target.length > 0 ) {\n \n // if collection, comparison will be done uppon the `id` attribute\n if (\n typeof(options[0]) != 'undefined' \n && typeof (options[0]) == 'object' \n && options[0] != null \n && typeof(options[0][keyComparison]) != 'undefined'\n && typeof(target[0]) == 'object' \n && typeof(target[0][keyComparison]) != 'undefined'\n ) {\n\n newTarget = (Array.isArray(target)) ? Array.from(target) : JSON.clone(target);\n var _options = JSON.clone(options);\n var next = null;\n \n i = 0;\n a = 0; aLen = newTarget.length;\n for (; a < aLen; ++a) {\n newTargetIds.push(newTarget[a][keyComparison]);\n }\n a = 0;\n for (; a < aLen; ++a) {\n \n end:\n for (var n = next || 0, nLen = _options.length; n < nLen; ++n) {\n \n if (\n _options[n] != null && typeof(_options[n][keyComparison]) != 'undefined' && _options[n][keyComparison] !== newTarget[a][keyComparison]\n\n ) {\n \n if ( newTargetIds.indexOf(_options[n][keyComparison]) == -1 ) {\n newTarget.push(_options[n]);\n newTargetIds.push(_options[n][keyComparison]);\n\n next = n+1; \n\n if (aLen < nLen)\n ++aLen;\n\n break end; \n }\n \n } else if( _options[n] != null && typeof(_options[n][keyComparison]) != 'undefined' && _options[n][keyComparison] === newTarget[a][keyComparison] ) {\n\n next = n+1;\n\n //break end;\n\n } else {\n break end;\n }\n }\n\n\n }\n\n return newTarget;\n\n\n } else { // normal case `arrays`\n a = 0;\n for (; a < options.length; ++a ) {\n if ( target.indexOf(options[a]) > -1 && override) {\n target.splice(target.indexOf(options[a]), 1, options[a])\n } else if ( typeof(newTarget[a]) == 'undefined' && typeof(options[a]) == 'object' ) {\n // merge using index \n newTarget = target;\n\n if (typeof (newTarget[a]) == 'undefined')\n newTarget[a] = {};\n \n \n for (let k in options[a]) {\n if (!newTarget[a].hasOwnProperty(k)) {\n newTarget[a][k] = options[a][k]\n }\n } \n \n } else {\n // fixing a = [25]; b = [25,25];\n // result must be [25,25]\n if (\n !override\n && newTarget.indexOf(options[a]) > -1 \n && typeof(options[a]) == 'number'\n // ok but not if @ same position\n //&& options[a] !== newTarget[a]\n ) {\n if (options[a] !== newTarget[a]) {\n newTarget.push(options[a]);\n continue\n }\n \n //break;\n }\n \n \n if (\n typeof (target[a]) != 'undefined'\n && !/null/i.test(target[a])\n && typeof (target[a][keyComparison]) != 'undefined'\n && typeof (options[a]) != 'undefined'\n && typeof (options[a][keyComparison]) != 'undefined'\n && target[a][keyComparison] == options[a][keyComparison]\n ) {\n if (override)\n newTarget[a] = options[a]\n else\n newTarget[a] = target[a]\n } else if (newTarget.indexOf(options[a]) == -1 /**&& typeof(options[a]) == 'string'*/) {\n newTarget.push(options[a]);\n }\n \n \n }\n }\n }\n\n\n }\n\n if ( newTarget.length > 0 && target.length > 0 || newTarget.length == 0 && target.length == 0 ) {\n return newTarget\n }\n }\n mergeArray.prototype.setKeyComparison = function(keyComparison) {\n this.keyComparison = keyComparison\n }\n\n\n /**\n * Check if object before merging.\n * */\n var isObject = function (obj) {\n if (\n !obj\n || {}.toString.call(obj) !== '[object Object]'\n || obj.nodeType\n || obj.setInterval\n ) {\n return false\n }\n\n var hasOwn = {}.hasOwnProperty;\n var hasOwnConstructor = hasOwn.call(obj, 'constructor');\n // added test for node > v6\n var hasMethodPrototyped = ( typeof(obj.constructor) != 'undefined' ) ? hasOwn.call(obj.constructor.prototype, 'isPrototypeOf') : false;\n\n\n if (\n obj.constructor && !hasOwnConstructor && !hasMethodPrototyped\n ) {\n return false\n }\n\n //Own properties are enumerated firstly, so to speed up,\n //if last one is own, then all properties are own.\n var key;\n return key === undefined || hasOwn.call(obj, key)\n }\n\n browse.setKeyComparison = function(keyComparison) {\n \n mergeArray.keyComparison = keyComparison;\n \n return browse\n }\n \n browse.getKeyComparison = function() {\n \n var keyComparison = mergeArray.keyComparison || 'id';\n \n // reset for the next merge\n mergeArray.keyComparison = 'id';\n \n return keyComparison\n }\n \n // clone target & source to prevent mutations from the originals\n // if (!browse.originalValueshasBeenCached) { \n // for (let a = 0, aLen = arguments.length; a < aLen; a++) {\n // if ( typeof(arguments[a]) == 'object' ) {\n // arguments[a] = JSON.clone(arguments[a]);\n // }\n // }\n // browse.originalValueshasBeenCached = true; \n // }\n \n return browse\n}\n\nif ( ( typeof(module) !== 'undefined' ) && module.exports ) {\n // for unit tests\n if ( typeof(JSON.clone) == 'undefined' ) {\n require('../../../helpers');\n }\n // Publish as node.js module\n module.exports = Merge()\n} else if ( typeof(define) === 'function' && define.amd) {\n // Publish as AMD module\n define( 'utils/merge',[],function() { return Merge() })\n};\n",
|
|
35
|
-
"function registerEvents(plugin, events) {\n gina.registeredEvents[plugin] = events\n}\nfunction mergeEventProps(evt, proxiedEvent) {\n for (let p in proxiedEvent) {\n // add only missing props\n if ( typeof(evt[p]) == 'undefined' ) {\n evt[p] = proxiedEvent[p];\n }\n }\n return evt;\n}\n/**\n * addListener\n * \n * @param {object} target \n * @param {object} element \n * @param {string|array} name \n * @param {callback} callback \n */\nfunction addListener(target, element, name, callback) {\n \n var registerListener = function(target, element, name, callback) {\n \n if ( typeof(target.event) != 'undefined' && target.event.isTouchSupported && /^(click|mouseout|mouseover)/.test(name) && target.event[name].indexOf(element) == -1) {\n target.event[name][target.event[name].length] = element\n }\n\n if (typeof(element) != 'undefined' && element != null) {\n if (element.addEventListener) {\n element.addEventListener(name, callback, false)\n } else if (element.attachEvent) {\n element.attachEvent('on' + name, callback)\n }\n } else {\n target.customEvent.addListener(name, callback)\n }\n\n gina.events[name] = ( typeof(element.id) != 'undefined' && typeof(element.id) != 'object' ) ? element.id : element.getAttribute('id');\n }\n \n var i = 0, len = null;\n if ( Array.isArray(name) ) { \n len = name.length; \n for (; i < len; i++) {\n registerListener(target, element, name[i], callback)\n }\n } else {\n if ( Array.isArray(element) ) {\n i = 0;\n len = element.length;\n for (; i < len; i++) {\n let evtName = ( /\\.$/.test(name) ) ? name + element[i].id : name;\n registerListener(target, element[i], evtName, callback);\n }\n } else {\n name = ( /\\.$/.test(name) ) ? name + element.id : name;\n registerListener(target, element, name, callback);\n } \n }\n \n}\n/**\n * triggerEvent\n * @param {object} target - targeted domain\n * @param {object} element - HTMLFormElement \n * @param {string} name - event ID\n * @param {object|array|string} args - details\n * @param {object} [proxiedEvent]\n */\nfunction triggerEvent (target, element, name, args, proxiedEvent) {\n if (typeof(element) != 'undefined' && element != null) {\n var evt = null, isDefaultPrevented = false, isAttachedToDOM = false, merge = null;\n // if (proxiedEvent) {\n // merge = require('utils/merge');\n // }\n // done separately because it can be listen at the same time by the user & by gina\n if ( jQuery ) { //thru jQuery if detected\n\n // Check if listener is in use: e.g $('#selector').on('eventName', cb)\n var $events = null; // attached events list\n // Before jQuery 1.7\n var version = jQuery['fn']['jquery'].split(/\\./);\n if (version.length > 2) {\n version = version.splice(0,2).join('.');\n } else {\n version = version.join('.');\n }\n\n if (version <= '1.7') {\n $events = jQuery(element)['data']('events')\n } else {// From 1.8 +\n $events = jQuery['_data'](jQuery(element)[0], \"events\")\n }\n\n isAttachedToDOM = ( typeof($events) != 'undefined' && typeof($events[name]) != 'undefined' ) ? true : false;\n\n if (isAttachedToDOM) { // only trigger if attached\n evt = jQuery.Event( name );\n jQuery(element)['trigger'](evt, args);\n isDefaultPrevented = evt['isDefaultPrevented']();\n }\n\n\n }\n \n if (window.CustomEvent || document.createEvent) {\n \n \n if (window.CustomEvent) { // new method from ie9 \n evt = new CustomEvent(name, {\n 'detail' : args,\n 'bubbles' : true,\n 'cancelable': true,\n 'target' : element\n })\n } else { // before ie9\n\n evt = document.createEvent('HTMLEvents');\n // OR\n // evt = document.createEvent('Event');\n\n evt['detail'] = args;\n evt['target'] = element;\n evt.initEvent(name, true, true);\n\n evt['eventName'] = name;\n\n }\n if (proxiedEvent) {\n // merging props \n evt = mergeEventProps(evt, proxiedEvent);\n }\n\n if ( typeof(evt.defaultPrevented) != 'undefined' && evt.defaultPrevented )\n isDefaultPrevented = evt.defaultPrevented;\n\n if ( !isDefaultPrevented ) {\n //console.log('dispatching ['+name+'] to ', element.id, isAttachedToDOM, evt.detail);\n element.dispatchEvent(evt)\n }\n\n } else if (document.createEventObject) { // non standard\n \n evt = document.createEventObject();\n evt.srcElement.id = element.id;\n evt.detail = args;\n evt.target = element;\n \n if (proxiedEvent) { \n // merging props \n evt = mergeEventProps(evt, proxiedEvent);\n }\n \n element.fireEvent('on' + name, evt);\n }\n\n } else {\n target.customEvent.fire(name, args);\n }\n}\n\nfunction cancelEvent(event) {\n if (typeof(event) != 'undefined' && event != null) {\n\n event.cancelBubble = true;\n\n if (event.preventDefault) {\n event.preventDefault()\n }\n\n if (event.stopPropagation) {\n event.stopPropagation()\n }\n\n\n event.returnValue = false;\n }\n}\n\nfunction setupXhr(options) {\n var xhr = null;\n if (window.XMLHttpRequest) { // Mozilla, Safari, ...\n xhr = new XMLHttpRequest();\n } else if (window.ActiveXObject) { // IE\n try {\n xhr = new ActiveXObject(\"Msxml2.XMLHTTP\");\n } catch (e) {\n try {\n xhr = new ActiveXObject(\"Microsoft.XMLHTTP\");\n }\n catch (e) {}\n }\n }\n if ( typeof(options) != 'undefined' ) {\n if ( !options.url || typeof(options.url) == 'undefined' ) {\n throw new Error('Missing `options.url`');\n }\n if ( typeof(options.method) == 'undefined' ) {\n options.method = 'GET';\n }\n options.method = options.method.toUpperCase();\n \n if ( options.withCredentials ) {\n if ('withCredentials' in xhr) {\n // XHR for Chrome/Firefox/Opera/Safari.\n if (options.isSynchrone) {\n xhr.open(options.method, options.url, options.isSynchrone)\n } else {\n xhr.open(options.method, options.url)\n }\n } else if ( typeof XDomainRequest != 'undefined' ) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n xhr.open(options.method, options.url);\n } else {\n // CORS not supported.\n xhr = null;\n result = 'CORS not supported: the server is missing the header `\"Access-Control-Allow-Credentials\": true` ';\n triggerEvent(gina, $target, 'error.' + id, result);\n\n return;\n }\n \n if ( typeof(options.responseType) != 'undefined' ) {\n xhr.responseType = options.responseType;\n } else {\n xhr.responseType = '';\n }\n\n xhr.withCredentials = true;\n } else {\n if (options.isSynchrone) {\n xhr.open(options.method, options.url, options.isSynchrone);\n } else {\n xhr.open(options.method, options.url);\n }\n }\n\n // setting up headers - all but Content-Type ; it will be set right before .send() is called\n for (var hearder in options.headers) {\n //if ( hearder == 'Content-Type' && typeof (enctype) != 'undefined' && enctype != null && enctype != '') {\n // options.headers[hearder] = enctype\n //}\n if (hearder == 'Content-Type' && typeof (enctype) != 'undefined' && enctype != null && enctype != '')\n continue;\n\n xhr.setRequestHeader(hearder, options.headers[hearder]);\n }\n }\n return xhr;\n}\n\n/**\n * handleXhr\n * \n * @param {object} xhr - instance\n * @param {object} $el - dom objet element \n * @param {object} options \n */ \nfunction handleXhr(xhr, $el, options, require) {\n \n if (!xhr)\n throw new Error('No `xhr` object initiated');\n \n //var merge = require('utils/merge');\n \n var blob = null\n , isAttachment = null // handle download\n , contentType = null\n , result = null \n , id = null\n , $link = options.$link || null\n , $form = options.$form || null\n , $target = null\n ;\n delete options.$link;\n delete options.$form;\n \n if ($form || $link) {\n if ($link) {\n // not the link element but the link elements collection : like for popins main container\n $link.target = document.getElementById($link.id);\n $target = gina.link.target;\n id = gina.link.id;\n \n // copy $el attributes to $target\n // for (var prop in $link) {\n // if ( !$target[prop] )\n // $target[prop] = $link[prop];\n // }\n } else { // forms\n $target = $form.target;\n id = $target.getAttribute('id');\n } \n } else {\n $target = $el;\n id = $target.getAttribute('id');\n }\n \n // forward callback to HTML data event attribute through `hform` status\n var hLinkIsRequired = ( $link && $el.getAttribute('data-gina-link-event-on-success') || $link && $el.getAttribute('data-gina-link-event-on-error') ) ? true : false; \n // if (hLinkIsRequired && $link)\n // listenToXhrEvents($link, 'link');\n \n // forward callback to HTML data event attribute through `hform` status\n var hFormIsRequired = ( $form && $target.getAttribute('data-gina-form-event-on-submit-success') || $form && $target.getAttribute('data-gina-form-event-on-submit-error') ) ? true : false;\n // success -> data-gina-form-event-on-submit-success\n // error -> data-gina-form-event-on-submit-error\n if (hFormIsRequired && $form)\n listenToXhrEvents($form, 'form');\n \n \n // to upload, use `multipart/form-data` for `enctype`\n var enctype = $el.getAttribute('enctype') || options.headers['Content-Type'];\n \n // setting up headers - all but Content-Type ; it will be set right before .send() is called\n for (var hearder in options.headers) {\n //if ( hearder == 'Content-Type' && typeof (enctype) != 'undefined' && enctype != null && enctype != '') {\n // options.headers[hearder] = enctype\n //}\n if (hearder == 'Content-Type' && typeof (enctype) != 'undefined' && enctype != null && enctype != '')\n continue;\n\n xhr.setRequestHeader(hearder, options.headers[hearder]);\n } \n xhr.withCredentials = ( typeof(options.withCredentials) != 'undefined' ) ? options.withCredentials : false;\n \n \n // catching errors\n xhr.onerror = function(event, err) {\n \n var error = 'Transaction error: might be due to the server CORS settings.\\nPlease, check the console for more details.';\n var result = {\n 'status': xhr.status || 500, //500,\n 'error' : error\n }; \n \n var resultIsObject = true;\n if ($form)\n $form.eventData.error = result;\n \n if ($link)\n $link.eventData.error = result;\n \n //updateToolbar(result, resultIsObject);\n window.ginaToolbar.update('data-xhr', result, resultIsObject);\n \n triggerEvent(gina, $target, 'error.' + id, result);\n \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hform', result);\n \n if (hLinkIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hlink', result);\n }\n \n // catching ready state cb\n xhr.onreadystatechange = function (event) {\n // In case the user is also redirecting\n var redirectDelay = (/Google Inc/i.test(navigator.vendor)) ? 50 : 0;\n \n if (xhr.readyState == 2) { // responseType interception\n isAttachment = ( /^attachment\\;/.test( xhr.getResponseHeader('Content-Disposition') ) ) ? true : false; \n // force blob response type\n if ( !xhr.responseType && isAttachment ) {\n xhr.responseType = 'blob';\n }\n }\n\n if (xhr.readyState == 4) {\n blob = null;\n contentType = xhr.getResponseHeader('Content-Type'); \n \n // 200, 201, 201' etc ...\n if( /^2/.test(xhr.status) ) {\n\n try { \n \n // handling blob xhr download\n if ( /blob/.test(xhr.responseType) || isAttachment ) {\n if ( typeof(contentType) == 'undefined' || contentType == null) {\n contentType = 'application/octet-stream';\n }\n \n blob = new Blob([this.response], { type: contentType });\n \n //Create a link element, hide it, direct it towards the blob, and then 'click' it programatically\n var a = document.createElement('a');\n a.style = 'display: none';\n document.body.appendChild(a);\n //Create a DOMString representing the blob and point the link element towards it\n var url = window.URL.createObjectURL(blob);\n a.href = url;\n var contentDisposition = xhr.getResponseHeader('Content-Disposition');\n a.download = contentDisposition.match('\\=(.*)')[0].substr(1);\n //programatically click the link to trigger the download\n a.click();\n //release the reference to the file by revoking the Object URL\n window.URL.revokeObjectURL(url);\n \n result = {\n status : xhr.status,\n statusText : xhr.statusText,\n responseType : blob.type,\n type : blob.type,\n size : blob.size \n }\n \n } \n\n \n if ( !result && /\\/json/.test( contentType ) ) {\n result = JSON.parse(xhr.responseText);\n \n if ( typeof(result.status) == 'undefined' )\n result.status = xhr.status || 200;\n }\n \n if ( !result && /\\/html/.test( contentType ) ) {\n \n result = {\n contentType : contentType,\n content : xhr.responseText\n };\n \n if ( typeof(result.status) == 'undefined' )\n result.status = xhr.status;\n \n // if hasPopinHandler & popinIsBinded\n if ( typeof(gina.popin) != 'undefined' && gina.hasPopinHandler ) {\n \n // select popin by id\n var $popin = gina.popin.getActivePopin();\n \n if ($popin) {\n \n XHRData = {};\n // update toolbar\n \n try {\n XHRData = new DOMParser().parseFromString(result.content, 'text/html').getElementById('gina-without-layout-xhr-data');\n XHRData = JSON.parse(decodeURIComponent(XHRData.value));\n \n XHRView = new DOMParser().parseFromString(result.content, 'text/html').getElementById('gina-without-layout-xhr-view'); \n XHRView = JSON.parse(decodeURIComponent(XHRView.value));\n \n // update data tab \n if ( gina && typeof(window.ginaToolbar) && typeof(XHRData) != 'undefined' ) {\n window.ginaToolbar.update('data-xhr', XHRData);\n }\n \n // update view tab \n if ( gina && typeof(window.ginaToolbar) && typeof(XHRView) != 'undefined' ) {\n window.ginaToolbar.update('view-xhr', XHRView);\n } \n\n } catch (err) {\n throw err\n } \n \n $popin.loadContent(result.content);\n \n result = XHRData;\n triggerEvent(gina, $target, 'success.' + id, result);\n \n return;\n } \n \n }\n }\n \n if (!result) { // normal case\n result = xhr.responseText; \n }\n \n if ($form)\n $form.eventData.success = result;\n\n XHRData = result;\n // update toolbar\n if ( gina && typeof(window.ginaToolbar) == 'object' && XHRData ) {\n try {\n // don't refresh for html datas\n if ( typeof(XHRData) != 'undefined' && /\\/html/.test(contentType) ) {\n window.ginaToolbar.update('data-xhr', XHRData);\n }\n\n } catch (err) {\n throw err\n }\n }\n\n triggerEvent(gina, $target, 'success.' + id, result);\n \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'success.' + id + '.hform', result);\n \n if (hLinkIsRequired)\n triggerEvent(gina, $target, 'success.' + id + '.hlink', result);\n \n } catch (err) {\n\n result = {\n status: 422,\n error : err.message,\n stack : err.stack\n\n };\n \n if ($form)\n $form.eventData.error = result;\n \n\n XHRData = result; \n // update toolbar\n if ( gina && typeof(window.ginaToolbar) == 'object' && XHRData ) {\n try {\n\n if ( typeof(XHRData) != 'undefined' ) {\n window.ginaToolbar.update('data-xhr', XHRData);\n }\n\n } catch (err) {\n throw err\n }\n }\n\n triggerEvent(gina, $target, 'error.' + id, result);\n if (hFormIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hform', result);\n \n if (hLinkIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hlink', result);\n }\n \n // handle redirect\n if ( typeof(result) != 'undefined' && typeof(result.location) != 'undefined' ) { \n window.location.hash = ''; //removing hashtag \n \n // if ( window.location.host == gina.config.hostname && /^(http|https)\\:\\/\\//.test(result.location) ) { // same origin\n // result.location = result.location.replace( new RegExp(gina.config.hostname), '' );\n // } else { // external - need to remove `X-Requested-With` from `options.headers`\n result.location = (!/^http/.test(result.location) && !/^\\//.test(result.location) ) ? location.protocol +'//' + result.location : result.location;\n //} \n \n return setTimeout(() => {\n window.location.href = result.location;\n }, redirectDelay); \n }\n\n } else if ( xhr.status != 0) {\n \n result = { 'status': xhr.status, 'message': '' };\n // handling blob xhr error\n if ( /blob/.test(xhr.responseType) ) {\n \n blob = new Blob([this.response], { type: 'text/plain' });\n \n var reader = new FileReader(), blobError = '';\n \n // This fires after the blob has been read/loaded.\n reader.addEventListener('loadend', (e) => {\n \n if ( /string/i.test(typeof(e.srcElement.result)) ) {\n blobError += e.srcElement.result;\n } else if ( typeof(e.srcElement.result) == 'object' ) {\n result = merge(result, e.srcElement.result)\n } else {\n result.message += e.srcElement.result\n }\n \n // once ready\n if ( /^2/.test(reader.readyState) ) {\n \n if ( /^(\\{|\\[)/.test( blobError ) ) {\n try {\n result = merge( result, JSON.parse(blobError) )\n } catch(err) {\n result = merge(result, err)\n } \n }\n \n if (!result.message)\n delete result.message;\n \n if ($form)\n $form.eventData.error = result;\n\n // forward appplication errors to forms.errors when available\n if ( typeof(result) != 'undefined' && typeof(result.error) != 'undefined' && result.error.fields && typeof(result.error.fields) == 'object') {\n var formsErrors = {}, errCount = 0;\n for (var f in result.error.fields) {\n ++errCount;\n formsErrors[f] = { isApplicationValidationError: result.error.fields[f] };\n }\n\n if (errCount > 0) {\n handleErrorsDisplay($form.target, formsErrors);\n }\n }\n\n // update toolbar\n XHRData = result;\n if ( gina && typeof(window.ginaToolbar) == 'object' && XHRData ) {\n try {\n // update toolbar\n window.ginaToolbar.update('data-xhr', XHRData );\n\n } catch (err) {\n throw err\n }\n }\n\n triggerEvent(gina, $target, 'error.' + id, result);\n \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hform', result);\n \n if (hLinkIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hlink', result);\n }\n return;\n \n \n });\n\n // Start reading the blob as text.\n reader.readAsText(blob);\n \n } else { // normal case\n \n if ( /^(\\{|\\[).test( xhr.responseText ) /) {\n\n try {\n result = merge( result, JSON.parse(xhr.responseText) )\n } catch (err) {\n result = merge(result, err)\n }\n\n } else if ( typeof(xhr.responseText) == 'object' ) {\n result = merge(result, xhr.responseText)\n } else {\n result.message = xhr.responseText\n }\n\n if ($form)\n $form.eventData.error = result;\n\n // forward appplication errors to forms.errors when available\n if ( typeof(result) != 'undefined' && typeof(result.error) != 'undefined' && result.error.fields && typeof(result.error.fields) == 'object') {\n var formsErrors = {}, errCount = 0;\n for (var f in result.error.fields) {\n ++errCount;\n formsErrors[f] = { isApplicationValidationError: result.error.fields[f] };\n }\n\n if (errCount > 0) {\n handleErrorsDisplay($form.target, formsErrors);\n }\n }\n\n // update toolbar\n XHRData = result;\n if ( gina && typeof(window.ginaToolbar) == \"object\" && XHRData ) {\n try {\n // update toolbar\n window.ginaToolbar.update('data-xhr', XHRData );\n\n } catch (err) {\n throw err\n }\n }\n\n triggerEvent(gina, $target, 'error.' + id, result);\n \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hform', result);\n \n if (hLinkIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hlink', result); \n }\n \n return;\n\n \n }\n }\n };\n \n // catching request progress\n xhr.onprogress = function(event) {\n \n var percentComplete = '0';\n if (event.lengthComputable) {\n percentComplete = event.loaded / event.total;\n percentComplete = parseInt(percentComplete * 100);\n\n }\n\n //var percentComplete = (event.position / event.totalSize)*100;\n var result = {\n 'status': 100,\n 'progress': percentComplete\n };\n\n if ($form)\n $form.eventData.onprogress = result;\n\n triggerEvent(gina, $target, 'progress.' + id, result);\n return;\n };\n\n // catching timeout\n xhr.ontimeout = function (event) {\n result = {\n 'status': 408,\n 'error': 'Request Timeout'\n };\n\n if ($form)\n $form.eventData.ontimeout = result;\n\n triggerEvent(gina, $target, 'error.' + id, result);\n \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hform', result);\n \n if (hLinkIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hlink', result);\n \n return;\n };\n \n \n //return xhr;\n}\n\nfunction removeListener(target, element, name, callback) {\n if (typeof(target.event) != 'undefined' && target.event.isTouchSupported && /^(click|mouseout|mouseover)/.test(name) && target.event[name].indexOf(element) != -1) {\n target.event[name].splice(target.event[name].indexOf(element), 1)\n }\n\n if (typeof(element) != 'undefined' && element != null) {\n if (element.removeEventListener) {\n //element.removeEventListener(name, callback, false);\n if ( Array.isArray(element) ) {\n i = 0;\n len = element.length;\n for (; i < len; i++) {\n let evtName = ( /\\.$/.test(name) ) ? name + element[i].id : name;\n element.removeEventListener(evtName, callback, false);\n if ( typeof(gina.events[evtName]) != 'undefined' ) {\n // removed ------> [evtName];\n delete gina.events[evtName]\n }\n }\n } else {\n name = ( /\\.$/.test(name) ) ? name + element.id : name;\n element.removeEventListener(name, callback, false);\n } \n } else if (element.attachEvent) {\n //element.detachEvent('on' + name, callback);\n if ( Array.isArray(element) ) {\n i = 0;\n len = element.length;\n for (; i < len; i++) {\n let evtName = ( /\\.$/.test(name) ) ? name + element[i].id : name;\n element.detachEvent('on' + evtName, callback);\n if ( typeof(gina.events[evtName]) != 'undefined' ) {\n // removed ------> [evtName];\n delete gina.events[evtName]\n }\n }\n } else {\n name = ( /\\.$/.test(name) ) ? name + element.id : name;\n element.detachEvent('on' + name, callback);\n } \n }\n } else {\n //target.customEvent.removeListener(name, callback)\n if ( Array.isArray(element) ) {\n i = 0;\n len = element.length;\n for (; i < len; i++) {\n let evtName = ( /\\.$/.test(name) ) ? name + element[i].id : name;\n target.customEvent.removeListener(evtName, callback);\n if ( typeof(gina.events[evtName]) != 'undefined' ) {\n // removed ------> [evtName];\n delete gina.events[evtName]\n }\n }\n } else {\n name = ( /\\.$/.test(name) ) ? name + element.id : name;\n target.customEvent.removeListener(name, callback)\n } \n }\n\n if ( typeof(gina.events[name]) != 'undefined' ) {\n // removed ------> [name];\n delete gina.events[name]\n }\n if ( typeof(callback) != 'undefined' ) {\n callback()\n }\n}\n\n\n\nfunction on(event, cb) {\n\n if (!this.plugin) throw new Error('No `plugin` reference found for this event: `'+ event);\n\n var events = gina.registeredEvents[this.plugin];\n\n if ( events.indexOf(event) < 0 && !/^init$/.test(event) && !/\\.hform$/.test(event) && !/\\.hlink$/.test(event) ) {\n cb(new Error('Event `'+ event +'` not handled by ginaEventHandler'))\n } else {\n var $target = null, id = null;\n if ( typeof(this.id) != 'undefined' && typeof(this.id) != 'object' ) {\n $target = this.target || this;\n id = this.id;\n } else if ( typeof(this.target) != 'undefined' ) {\n $target = this.target;\n if (!$target) {\n $target = this;\n }\n id = ( typeof($target.getAttribute) != 'undefined' ) ? $target.getAttribute('id') : this.id;\n } else {\n $target = this.target;\n id = instance.id;\n }\n\n if ( this.eventData && !$target.eventData)\n $target.eventData = this.eventData\n\n if ( /\\.(hform|hlink)$/.test(event) ) { \n event = ( /\\.hform$/.test(event) ) ? event.replace(/\\.hform$/, '.' + id + '.hform') : event.replace(/\\.hlink$/, '.' + id + '.hlink');\n } else { // normal case\n event += '.' + id;\n }\n \n\n if (!gina.events[event]) {\n\n addListener(gina, $target, event, function(e) {\n\n //if ( typeof(e.defaultPrevented) != 'undefined' && e.defaultPrevented)\n cancelEvent(e);\n\n var data = null;\n\n if (e['detail']) {\n data = e['detail'];\n } else if ( typeof(this.eventData.submit) != 'undefined' ) {\n data = this.eventData.submit\n } else if ( typeof(this.eventData.error) != 'undefined' ) {\n data = this.eventData.error;\n } else if ( typeof(this.eventData.success) != 'undefined' ) {\n data = this.eventData.success;\n }\n\n if (cb)\n cb(e, data);\n \n //triggerEvent(gina, e.currentTarget, e.type);\n });\n\n if (this.initialized && !this.isReady)\n triggerEvent(gina, $target, 'init.' + id);\n\n }\n\n return this\n }\n \n // Nothing can be added after on() \n \n \n var listenToXhrEvents = function($el, type) {\n\n\n //data-gina-{type}-event-on-success\n var htmlSuccesEventCallback = $el.target.getAttribute('data-gina-'+ type +'-event-on-success') || null;\n if (htmlSuccesEventCallback != null) {\n\n if ( /\\((.*)\\)/.test(htmlSuccesEventCallback) ) {\n eval(htmlSuccesEventCallback)\n } else {\n $el.on('success.h'+ type, window[htmlSuccesEventCallback])\n }\n }\n\n //data-gina-{type}-event-on-error\n var htmlErrorEventCallback = $el.target.getAttribute('data-gina-'+ type +'-event-on-error') || null;\n if (htmlErrorEventCallback != null) {\n if ( /\\((.*)\\)/.test(htmlErrorEventCallback) ) {\n eval(htmlErrorEventCallback)\n } else {\n $el.on('error.h'+ type, window[htmlErrorEventCallback])\n }\n }\n }\n};\ndefine(\"utils/events\", function(){});\n\n",
|
|
36
|
-
"function PrototypesHelper(instance) {\n \n var isGFFCtx = ( ( typeof(module) !== 'undefined' ) && module.exports ) ? false : true;\n \n var local = instance || null;\n var envVars = null;\n // since for some cases we cannot use gina envVars directly\n if ( \n typeof(GINA_DIR) == 'undefined'\n && !isGFFCtx\n && typeof(process) != 'undefined' \n && process.argv.length > 3\n ) {\n if ( /^\\{/.test(process.argv[2]) ) {\n envVars = JSON.parse(process.argv[2]).envVars;\n }\n // minions case\n else if ( /\\.ctx$/.test(process.argv[2]) ) {\n var fs = require('fs');\n var envVarFile = process.argv[2].split(/\\-\\-argv\\-filename\\=/)[1];\n envVars = JSON.parse(fs.readFileSync(envVarFile).toString()).envVars;\n }\n \n }\n // else if (isGFFCtx) {\n // envVars = window;\n // }\n \n \n // dateFormat proto\n if ( local && typeof(local) != 'undefined' && typeof(local.dateFormat) != 'undefined' ) {\n for (let method in local.dateFormat) {\n \n if ( typeof(Date[method]) != 'undefined' )\n continue;\n \n Object.defineProperty( Date.prototype, method, {\n writable: false,\n enumerable: false,\n //If loaded several times, it can lead to an exception. That's why I put this.\n configurable: true,\n value: function() { \n \n var newArgs = { 0: this }, i = 1;\n for (var a in arguments) {\n newArgs[i] = arguments[a];\n ++i\n }\n newArgs.length = i;\n // don't touch this, we need the name\n const name = method;\n \n return local.dateFormat[name].apply(this, newArgs );\n }\n });\n \n }\n }\n\n if ( typeof(Array.clone) == 'undefined' ) {\n /**\n * clone array\n * \n * @returns {array} Return cloned array\n * @supress {misplacedTypeAnnotation}\n **/\n Object.defineProperty( Array.prototype, 'clone', {\n writable: false,\n enumerable: false,\n //If loaded several times, it can lead to an exception. That's why I put this.\n configurable: true,\n value: function(){ return this.slice(0); }\n });\n }\n \n if ( typeof(JSON.clone) == 'undefined' && !isGFFCtx ) {\n if ( typeof(envVars) != 'undefined' ) {\n JSON.clone = require( envVars.GINA_DIR +'/utils/prototypes.json_clone');\n } else {\n JSON.clone = require( GINA_DIR +'/utils/prototypes.json_clone');\n } \n }\n \n if ( typeof(JSON.escape) == 'undefined' ) {\n /**\n * JSON.escape\n * Escape special characters\n * \n * Changes made here must be reflected in: \n * - gina/utils/prototypes.js\n * - gina/framework/version/helpers/prototypes.js\n * - gina/framework/version/core/asset/js/plugin/src/gina/utils/polyfill.js\n * \n * @param {object} jsonStr\n * \n * @returns {object} escaped JSON string\n **/\n var escape = function(jsonStr){\n try {\n return jsonStr\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\")\n ;\n } catch (err) { \n throw err;\n }\n };\n \n JSON.escape = escape;\n }\n \n\n if ( typeof(Array.toString) == 'undefined' ) {\n Array.prototype.toString = function(){\n return this.join();\n };\n }\n\n if ( typeof(Array.inArray) == 'undefined' ) {\n Object.defineProperty( Array.prototype, 'inArray', {\n writable: false,\n enumerable: false,\n //If loaded several times, it can lead to an exception. That's why I put this.\n configurable: true,\n value: function(o){ return this.indexOf(o)!=-1 }\n });\n }\n \n if ( typeof(Array.from) == 'undefined' ) { // if not under ES6\n\n Object.defineProperty( Array.prototype, 'from', {\n writable: false,\n enumerable: false,\n //If loaded several times, it can lead to an exception. That's why I put this.\n configurable: true,\n value: function(a){\n var seen = {}\n , out = []\n , len = a.length\n , j = 0;\n\n for(var i = 0; i < len; i++) {\n var item = a[i];\n if(seen[item] !== 1) {\n seen[item] = 1;\n out[j++] = item\n }\n }\n\n return out\n }\n });\n }\n \n if ( typeof(Object.count) == 'undefined' ) {\n Object.defineProperty( Object.prototype, 'count', {\n writable: true,\n enumerable: false,\n //If loaded several times, it can lead to an exception. That's why I put this.\n configurable: true,\n value: function(){\n var i = 0;\n try {\n var self = this;\n if (this instanceof String) self = JSON.parse(this);\n \n for (var prop in this)\n if (this.hasOwnProperty(prop)) ++i;\n\n return i;\n } catch (err) {\n return i;\n }\n\n }\n });\n } \n\n \n \n if ( typeof(global) != 'undefined' && typeof(global.__stack) == 'undefined' ) {\n /**\n * __stack Get current stack\n * @returns {Object} stack Current stack\n * @suppress {es5Strict}\n **/\n Object.defineProperty(global, '__stack', {\n //If loaded several times, it can lead to an exception. That's why I put this.\n configurable: true,\n get: function(){\n var orig = Error.prepareStackTrace;\n Error.prepareStackTrace = function(_, stack){\n return stack;\n };\n var err = new Error;\n /** @suppress {es5Strict} */\n Error.captureStackTrace(err, arguments.callee);\n var stack = err.stack;\n Error.prepareStackTrace = orig;\n return stack;\n }\n });\n }\n \n \n}\n\nif ( ( typeof(module) !== 'undefined' ) && module.exports ) {\n // Publish as node.js module\n module.exports = PrototypesHelper\n} else if ( typeof(define) === 'function' && define.amd) {\n // Publish as AMD module\n define( 'helpers/prototypes',[],function() { return PrototypesHelper })\n}\n ;\n",
|
|
37
|
-
"/*\n * This file is part of the gina package.\n * Copyright (c) 2009-2022 Rhinostone <contact@gina.io>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n/**\n * Credits & thanks to Steven Levithan :)\n * http://blog.stevenlevithan.com/archives/date-time-format\n * \n * \n * \n * Original Copyrights\n * Date Format 1.2.3\n * (c) 2007-2009 Steven Levithan <stevenlevithan.com>\n * MIT license\n *\n * Includes enhancements by Scott Trenda <scott.trenda.net>\n * and Kris Kowal <cixar.com/~kris.kowal/>\n *\n * Accepts a date, a mask, or a date and a mask.\n * Returns a formatted version of the given date.\n * The date defaults to the current date/time.\n * The mask defaults to dateFormat.masks.default.\n *\n * @param {string} date\n * @param {string} mask\n */\nfunction DateFormatHelper() {\n \n var isGFFCtx = ( ( typeof(module) !== 'undefined' ) && module.exports ) ? false : true;\n var merge = (isGFFCtx) ? require('utils/merge') : require('./../lib/merge');\n \n \n // if ( typeof(define) === 'function' && define.amd ) {\n // var Date = this.Date;\n // }\n \n var self = {};\n // language-country\n self.culture = 'en-US'; // by default\n self.lang = 'en'; // by default\n\n self.masks = {\n // i18n\n \"default\": \"ddd mmm dd yyyy HH:MM:ss\",\n shortDate: \"m/d/yy\",\n shortDate2: \"mm/dd/yyyy\",\n mediumDate: \"mmm d, yyyy\",\n longDate: \"mmmm d, yyyy\",\n fullDate: \"dddd, mmmm d, yyyy\",\n // common\n cookieDate: \"GMT:ddd, dd mmm yyyy HH:MM:ss\",\n logger: \"[yyyy mmm dd HH:MM:ss]\",\n shortTime: \"h:MM TT\",\n shortTime2: \"h:MM\",\n mediumTime: \"h:MM:ss TT\",\n mediumTime2: \"h:MM:ss\",\n longTime: \"h:MM:ss TT Z\",\n longTime2: \"h:MM:ss TT\",\n concatenatedDate: \"yyyymmdd\",\n isoDate: \"yyyy-mm-dd\",\n isoTime: \"HH:MM:ss\",\n shortIsoTime: \"HH:MM\",\n longIsoTime: \"HH:MM:ss TT\",\n isoDateTime: \"yyyy-mm-dd'T'HH:MM:ss\",\n isoUtcDateTime: \"UTC:yyyy-mm-dd'T'HH:MM:ss'Z'\"\n };\n \n self.i18n = {\n 'en': {\n dayNames: [\n \"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\",\n \"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"\n ],\n monthNames: [\n \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\",\n \"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"\n ],\n masks: {\n \"default\": \"ddd mmm dd yyyy HH:MM:ss\",\n shortDate: \"m/d/yy\",\n shortDate2: \"mm/dd/yyyy\",\n mediumDate: \"mmm d, yyyy\",\n longDate: \"mmmm d, yyyy\",\n fullDate: \"dddd, mmmm d, yyyy\"\n }\n },\n 'fr': {\n dayNames: [\n \"dim\", \"lun\", \"mar\", \"mer\", \"jeu\", \"ven\", \"sam\",\n \"dimanche\", \"lundi\", \"mardi\", \"mercredi\", \"jeudi\", \"vendredi\", \"samedi\"\n ],\n monthNames: [\n \"Jan\", \"Fév\", \"Mar\", \"Avr\", \"Mai\", \"Jui\", \"Juil\", \"Aoû\", \"Sep\", \"Oct\", \"Nov\", \"Déc\",\n \"Janvier\", \"Février\", \"Mars\", \"Avril\", \"Mai\", \"Juin\", \"Juillet\", \"Août\", \"Septembre\", \"Octobre\", \"Novembre\", \"Décembre\"\n ],\n masks: {\n \"default\": \"ddd mmm dd yyyy HH:MM:ss\",\n shortDate: \"d/m/yy\",\n shortDate2: \"dd/mm/yyyy\",\n mediumDate: \"d mmm, yyyy\",\n longDate: \"d mmmm, yyyy\",\n fullDate: \"dddd, d mmmm, yyyy\"\n }\n }\n };\n \n /**\n * \n * @param {string} culture (5 chars) | lang (2 chars) \n */\n var setCulture = function(date, culture) {\n if (/\\-/.test(culture) ) {\n self.culture = culture;\n self.lang = culture.split(/\\-/)[0];\n } else {\n self.lang = culture\n } \n \n return this\n }\n\n var format = function(date, mask, utc) {\n \n // if ( typeof(merge) == 'undefined' || !merge ) {\n // merge = (isGFFCtx) ? require('utils/merge') : require('./../lib/merge');\n \n // }\n \n var dF = self\n , i18n = dF.i18n[dF.lang] || dF.i18n['en']\n //, masksList = merge(i18n.masks, dF.masks)\n , masksList = null\n ;\n \n try {\n masksList = merge(i18n.masks, dF.masks);\n } catch( mergeErr) {\n // called from logger - redefinition needed for none-dev env: cache issue\n isGFFCtx = ( ( typeof(module) !== 'undefined' ) && module.exports ) ? false : true;\n merge = (isGFFCtx) ? require('utils/merge') : require('./../lib/merge');\n masksList = merge(i18n.masks, dF.masks);\n }\n \n if ( typeof(dF.i18n[dF.culture]) != 'undefined' ) {\n i18n = dF.i18n[dF.culture];\n if ( typeof(dF.i18n[dF.culture].mask) != 'undefined' ) {\n masksList = merge(i18n.masks, dF.masks)\n }\n }\n\n var\ttoken = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\\1?|[LloSZ]|\"[^\"]*\"|'[^']*'/g,\n timezone = /\\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\\d{4})?)\\b/g,\n timezoneClip = /[^-+\\dA-Z]/g,\n pad = function (val, len) {\n val = String(val);\n len = len || 2;\n while (val.length < len) val = \"0\" + val;\n return val;\n };\n\n // You can't provide utc if you skip other args (use the \"UTC:\" mask prefix)\n if (arguments.length == 1 && Object.prototype.toString.call(date) == \"[object String]\" && !/\\d/.test(date)) {\n mask = date;\n date = undefined;\n }\n\n // Passing date through Date applies Date.parse, if necessary\n date = date ? new Date(date) : new Date();\n if (isNaN(date)) throw SyntaxError(\"invalid date\");\n\n mask = String(masksList[mask] || mask || masksList[\"default\"]);\n\n // Allow setting the utc argument via the mask\n if (mask.slice(0, 4) == \"UTC:\") {\n mask = mask.slice(4);\n utc = true;\n }\n\n var\t_ = utc ? \"getUTC\" : \"get\",\n d = date[_ + \"Date\"](),\n D = date[_ + \"Day\"](),\n m = date[_ + \"Month\"](),\n y = date[_ + \"FullYear\"](),\n H = date[_ + \"Hours\"](),\n M = date[_ + \"Minutes\"](),\n s = date[_ + \"Seconds\"](),\n L = date[_ + \"Milliseconds\"](),\n o = utc ? 0 : date.getTimezoneOffset(),\n flags = {\n d: d,\n dd: pad(d),\n ddd: i18n.dayNames[D],\n dddd: i18n.dayNames[D + 7],\n m: m + 1,\n mm: pad(m + 1),\n mmm: i18n.monthNames[m],\n mmmm: i18n.monthNames[m + 12],\n yy: String(y).slice(2),\n yyyy: y,\n h: H % 12 || 12,\n hh: pad(H % 12 || 12),\n H: H,\n HH: pad(H),\n M: M,\n MM: pad(M),\n s: s,\n ss: pad(s),\n l: pad(L, 3),\n L: pad(L > 99 ? Math.round(L / 10) : L),\n t: H < 12 ? \"a\" : \"p\",\n tt: H < 12 ? \"am\" : \"pm\",\n T: H < 12 ? \"A\" : \"P\",\n TT: H < 12 ? \"AM\" : \"PM\",\n Z: utc ? \"UTC\" : (String(date).match(timezone) || [\"\"]).pop().replace(timezoneClip, \"\"),\n o: (o > 0 ? \"-\" : \"+\") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),\n S: [\"th\", \"st\", \"nd\", \"rd\"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]\n };\n\n\n\n return mask.replace(token, function ($0) {\n return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);\n });\n }\n\n /**\n * Get mask name from a given format\n *\n * @param {string} format\n *\n * @returns {string} maskName\n * */\n // var getMaskNameFromFormat = function (format) {\n\n // var name = \"default\";\n\n // for (var f in self.masks) {\n // if ( self.masks[f] === format )\n // return f\n // }\n\n // return name\n // }\n\n\n /**\n * Count days from the current date to another\n *\n * TODO - add a closure to `ignoreWeekend()` based on Lib::Validator\n * TODO - add a closure to `ignoreFromList(array)` based on Lib::Validator\n *\n * @param {object} dateTo\n * @returns {number} count\n * */\n var countDaysTo = function(date, dateTo) {\n\n if ( dateTo instanceof Date) {\n // The number of milliseconds in one day\n var oneDay = 1000 * 60 * 60 * 24\n\n // Convert both dates to milliseconds\n var date1Ms = date.getTime()\n var date2Ms = dateTo.getTime()\n\n // Calculate the difference in milliseconds\n var count = Math.abs(date1Ms - date2Ms)\n\n // Convert back to days and return\n return Math.round(count/oneDay);\n } else {\n throw new Error('dateTo is not instance of Date() !')\n }\n }\n\n /**\n * Will give an array of dates between the current date to a targeted date\n *\n * TODO - add a closure to `ignoreWeekend()` based on Utils::Validator\n * TODO - add a closure to `ignoreFromList(array)` based on Utils::Validator\n *\n * @param {object} dateTo\n * @param {string} [ mask ]\n *\n * @returns {array} dates\n * */\n var getDaysTo = function(date, dateTo, mask) {\n\n if ( dateTo instanceof Date) {\n var count = countDaysTo(date, dateTo)\n , month = date.getMonth()\n , year = date.getFullYear()\n , day = date.getDate() + 1\n , dateObj = new Date(year, month, day)\n , days = []\n , i = 0;\n\n for (; i < count; ++i) {\n if ( typeof(mask) != 'undefined' ) {\n days.push(new Date(dateObj).format(mask));\n } else {\n days.push(new Date(dateObj));\n }\n\n dateObj.setDate(dateObj.getDate() + 1);\n }\n\n return days || [];\n } else {\n throw new Error('dateTo is not instance of Date() !')\n }\n }\n\n var getDaysInMonth = function(date) {\n var month = date.getMonth();\n var year = date.getFullYear();\n var dateObj = new Date(year, month, 1);\n var days = [];\n while (dateObj.getMonth() === month) {\n days.push(new Date(dateObj));\n dateObj.setDate(dateObj.getDate() + 1);\n }\n return days;\n }\n \n \n /**\n * getQuarter\n * Get quarter number\n * To test : https://planetcalc.com/1252/\n * Based on fiscal year- See.: https://en.wikipedia.org/wiki/Fiscal_year\n * \n * TODO - Complete fiscalCodes\n * \n * @param {object} [date] if not defined, will take today's value\n * @param {string} [code] - us|eu\n * \n * @returns {number} quarterNumber - 1 to 4\n */\n var fiscalCodes = ['us', 'eu', 'corporate'];\n var getQuarter = function(date, code) {\n if (\n arguments.length == 1 \n && typeof(arguments[0]) == 'string'\n ) {\n if ( fiscalCodes.indexOf(arguments[0].toLowerCase()) < 0 ) {\n throw new Error('Quarter '+ arguments[0] +' code not supported !');\n }\n date = new Date();\n code = arguments[0]\n }\n if ( typeof(date) == 'undefined' ) {\n date = new Date();\n }\n if ( typeof(code) == 'undefined') {\n code = 'corporate';\n }\n \n code = code.toLowerCase();\n var q = [1,2,3,4]; // EU & corporates by default\n switch (code) {\n case 'us':\n q = [4,1,2,3];\n break;\n \n case 'corportate':\n case 'eu':\n q = [1,2,3,4]\n break;\n default:\n // EU & corporates by default\n q = [1,2,3,4];\n break;\n }\n \n return q[Math.floor(date.getMonth() / 3)];\n }\n \n /**\n * getHalfYear\n * \n * Based on fiscal year- See.: https://en.wikipedia.org/wiki/Fiscal_year\n * \n * @param {object} date \n * @param {string} code\n * \n * @returns halfYear number - 1 to 2\n */\n var getHalfYear = function(date, code) {\n if (\n arguments.length == 1 \n && typeof(arguments[0]) == 'string'\n ) {\n if ( fiscalCodes.indexOf(arguments[0].toLowerCase()) < 0 ) {\n throw new Error('Quarter '+ arguments[0] +' code not supported !');\n }\n date = new Date();\n code = arguments[0]\n }\n if ( typeof(date) == 'undefined' ) {\n date = new Date();\n }\n if ( typeof(code) == 'undefined') {\n code = 'corporate';\n }\n \n code = code.toLowerCase();\n \n return (date.getQuarter(code) <=2 ) ? 1 : 2;\n }\n \n /**\n * getWeekISO8601\n * Get week number\n * ISO 8601\n * To test : https://planetcalc.com/1252/\n * \n * @param {object} [date] if not defined, will take today's value\n * \n * @returns {number} weekNumber\n */\n var getWeekISO8601 = function(date) {\n // Copy date so don't modify original\n d = new Date(date.getFullYear(), date.getMonth(), date.getDate()); \n // Make Sunday's day number 7\n var dayNum = d.getDay() || 7;\n d.setDate(d.getDate() + 4 - dayNum);\n var yearStart = new Date(Date.parse(d.getFullYear(),0,1));\n \n return Math.ceil((((d - yearStart) / 86400000) + 1)/7)\n }\n \n /**\n * getWeek\n * Get week number\n * To test : https://planetcalc.com/1252/\n * \n * @param {object} [date] if not defined, will take today's value\n * \n * @returns {number} weekNumber - 1 to 53\n */\n var getWeek = function(date, standardMethod) {\n if ( typeof(date) == 'undefined' ) {\n date = new Date();\n }\n if ( typeof(standardMethod) == 'undefined') {\n standardMethod = 'ISO 8601';\n }\n \n standardMethod = standardMethod.replace(/\\s+/g, '').toLowerCase();\n switch (standardMethod) {\n case 'corporate':\n case 'eu':\n case 'iso8601':\n return getWeekISO8601(date)\n \n default:\n return getWeekISO8601(date)\n }\n }\n\n /**\n * Add or subtract hours\n * Adding 2 hours\n * => myDate.addHours(2)\n * Subtracting 10 hours\n * => myDate.addHours(-10)\n * */\n var addHours = function(date, h) {\n var copiedDate = new Date(date.getTime());\n copiedDate.setHours(copiedDate.getHours() + h);\n return copiedDate;\n }\n\n\n /**\n * Add or subtract days\n * Adding 2 days\n * => myDate.addDays(2)\n * Subtracting 10 days\n * => myDate.addDays(-10)\n * */\n var addDays = function(date, d) {\n var copiedDate = new Date(date.getTime());\n copiedDate.setHours(copiedDate.getHours() + d * 24);\n return copiedDate;\n }\n\n /**\n * Add or subtract years\n * Adding 2 days\n * => myDate.addYears(2)\n * Subtracting 10 years\n * => myDate.addYears(-10)\n * */\n var addYears = function(date, y) {\n var copiedDate = new Date(date.getTime());\n copiedDate.setFullYear(copiedDate.getFullYear() + y);\n return copiedDate;\n }\n\n var _proto = {\n setCulture : setCulture,\n format : format,\n countDaysTo : countDaysTo,\n getDaysTo : getDaysTo,\n getDaysInMonth : getDaysInMonth,\n getQuarter : getQuarter,\n getHalfYear : getHalfYear,\n getWeek : getWeek,\n addHours : addHours,\n addDays : addDays,\n addYears : addYears\n };\n \n return _proto\n\n};\n\nif ( ( typeof(module) !== 'undefined' ) && module.exports ) {\n // Publish as node.js module\n module.exports = DateFormatHelper\n} else if ( typeof(define) === 'function' && define.amd) {\n // Publish as AMD module\n define( 'helpers/dateFormat',[],function() { return DateFormatHelper })\n};\n",
|
|
38
|
-
"/*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */\n!function(a,b){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error(\"jQuery requires a window with a document\");return b(a)}:b(a)}(\"undefined\"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m=\"1.12.4\",n=function(a,b){return new n.fn.init(a,b)},o=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,p=/^-ms-/,q=/-([\\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:\"\",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for(\"boolean\"==typeof g&&(j=g,g=arguments[h]||{},h++),\"object\"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:\"jQuery\"+(m+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return\"function\"===n.type(a)},isArray:Array.isArray||function(a){return\"array\"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||\"object\"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,\"constructor\")&&!k.call(a.constructor.prototype,\"isPrototypeOf\"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+\"\":\"object\"==typeof a||\"function\"==typeof a?i[j.call(a)]||\"object\":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,\"ms-\").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?\"\":(a+\"\").replace(o,\"\")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,\"string\"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return\"string\"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),\"function\"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(a,b){i[\"[object \"+b+\"]\"]=b.toLowerCase()});function s(a){var b=!!a&&\"length\"in a&&a.length,c=n.type(a);return\"function\"===c||n.isWindow(a)?!1:\"array\"===c||0===b||\"number\"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u=\"sizzle\"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",L=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",M=\"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",N=\"\\\\[\"+L+\"*(\"+M+\")(?:\"+L+\"*([*^$|!~]?=)\"+L+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+M+\"))|)\"+L+\"*\\\\]\",O=\":(\"+M+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+N+\")*)|.*)\\\\)|)\",P=new RegExp(L+\"+\",\"g\"),Q=new RegExp(\"^\"+L+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+L+\"+$\",\"g\"),R=new RegExp(\"^\"+L+\"*,\"+L+\"*\"),S=new RegExp(\"^\"+L+\"*([>+~]|\"+L+\")\"+L+\"*\"),T=new RegExp(\"=\"+L+\"*([^\\\\]'\\\"]*?)\"+L+\"*\\\\]\",\"g\"),U=new RegExp(O),V=new RegExp(\"^\"+M+\"$\"),W={ID:new RegExp(\"^#(\"+M+\")\"),CLASS:new RegExp(\"^\\\\.(\"+M+\")\"),TAG:new RegExp(\"^(\"+M+\"|[*])\"),ATTR:new RegExp(\"^\"+N),PSEUDO:new RegExp(\"^\"+O),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+L+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+L+\"*(?:([+-]|)\"+L+\"*(\\\\d+)|))\"+L+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+K+\")$\",\"i\"),needsContext:new RegExp(\"^\"+L+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+L+\"*((?:-\\\\d)?\\\\d*)\"+L+\"*\\\\)|)(?=[^-]|$)\",\"i\")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\\d$/i,Z=/^[^{]+\\{\\s*\\[native \\w/,$=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,_=/[+~]/,aa=/'|\\\\/g,ba=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+L+\"?|(\"+L+\")|.)\",\"ig\"),ca=function(a,b,c){var d=\"0x\"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],\"string\"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+\" \"]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if(\"object\"!==b.nodeName.toLowerCase()){(k=b.getAttribute(\"id\"))?k=k.replace(aa,\"\\\\$&\"):b.setAttribute(\"id\",k=u),r=g(a),h=r.length,l=V.test(k)?\"#\"+k:\"[id='\"+k+\"']\";while(h--)r[h]=l+\" \"+qa(r[h]);s=r.join(\",\"),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute(\"id\")}}}return i(a.replace(Q,\"$1\"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+\" \")>d.cacheLength&&delete b[a.shift()],b[c+\" \"]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement(\"div\");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split(\"|\"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return\"input\"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return(\"input\"===c||\"button\"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&\"undefined\"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?\"HTML\"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener(\"unload\",da,!1):e.attachEvent&&e.attachEvent(\"onunload\",da)),c.attributes=ia(function(a){return a.className=\"i\",!a.getAttribute(\"className\")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment(\"\")),!a.getElementsByTagName(\"*\").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(\"undefined\"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute(\"id\")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c=\"undefined\"!=typeof a.getAttributeNode&&a.getAttributeNode(\"id\");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return\"undefined\"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if(\"*\"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return\"undefined\"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML=\"<a id='\"+u+\"'></a><select id='\"+u+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",a.querySelectorAll(\"[msallowcapture^='']\").length&&q.push(\"[*^$]=\"+L+\"*(?:''|\\\"\\\")\"),a.querySelectorAll(\"[selected]\").length||q.push(\"\\\\[\"+L+\"*(?:value|\"+K+\")\"),a.querySelectorAll(\"[id~=\"+u+\"-]\").length||q.push(\"~=\"),a.querySelectorAll(\":checked\").length||q.push(\":checked\"),a.querySelectorAll(\"a#\"+u+\"+*\").length||q.push(\".#.+[+~]\")}),ia(function(a){var b=n.createElement(\"input\");b.setAttribute(\"type\",\"hidden\"),a.appendChild(b).setAttribute(\"name\",\"D\"),a.querySelectorAll(\"[name=d]\").length&&q.push(\"name\"+L+\"*[*^$|!~]?=\"),a.querySelectorAll(\":enabled\").length||q.push(\":enabled\",\":disabled\"),a.querySelectorAll(\"*,:x\"),q.push(\",.*:\")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,\"div\"),s.call(a,\"[s!='']:x\"),r.push(\"!=\",O)}),q=q.length&&new RegExp(q.join(\"|\")),r=r.length&&new RegExp(r.join(\"|\")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,\"='$1']\"),c.matchesSelector&&p&&!A[b+\" \"]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error(\"Syntax error, unrecognized expression: \"+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c=\"\",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if(\"string\"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||\"\").replace(ba,ca),\"~=\"===a[2]&&(a[3]=\" \"+a[3]+\" \"),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),\"nth\"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*(\"even\"===a[3]||\"odd\"===a[3])),a[5]=+(a[7]+a[8]||\"odd\"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||\"\":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(\")\",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return\"*\"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+\" \"];return b||(b=new RegExp(\"(^|\"+L+\")\"+a+\"(\"+L+\"|$)\"))&&y(a,function(a){return b.test(\"string\"==typeof a.className&&a.className||\"undefined\"!=typeof a.getAttribute&&a.getAttribute(\"class\")||\"\")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?\"!=\"===b:b?(e+=\"\",\"=\"===b?e===c:\"!=\"===b?e!==c:\"^=\"===b?c&&0===e.indexOf(c):\"*=\"===b?c&&e.indexOf(c)>-1:\"$=\"===b?c&&e.slice(-c.length)===c:\"~=\"===b?(\" \"+e.replace(P,\" \")+\" \").indexOf(c)>-1:\"|=\"===b?e===c||e.slice(0,c.length+1)===c+\"-\":!1):!0}},CHILD:function(a,b,c,d,e){var f=\"nth\"!==a.slice(0,3),g=\"last\"!==a.slice(-4),h=\"of-type\"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?\"nextSibling\":\"previousSibling\",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p=\"only\"===a&&!o&&\"nextSibling\"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error(\"unsupported pseudo: \"+a);return e[u]?e(b):e.length>1?(c=[a,a,\"\",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,\"$1\"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||\"\")||fa.error(\"unsupported lang: \"+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute(\"xml:lang\")||b.getAttribute(\"lang\"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+\"-\");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&!!a.checked||\"option\"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&\"button\"===a.type||\"button\"===b},text:function(a){var b;return\"input\"===a.nodeName.toLowerCase()&&\"text\"===a.type&&(null==(b=a.getAttribute(\"type\"))||\"text\"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+\" \"];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q,\" \")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d=\"\";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&\"parentNode\"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||\"*\",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[\" \"],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:\" \"===a[i-2].type?\"*\":\"\"})).replace(Q,\"$1\"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s=\"0\",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG(\"*\",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+\" \"];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n=\"function\"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&\"ID\"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split(\"\").sort(B).join(\"\")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement(\"div\"))}),ia(function(a){return a.innerHTML=\"<a href='#'></a>\",\"#\"===a.firstChild.getAttribute(\"href\")})||ja(\"type|href|height|width\",function(a,b,c){return c?void 0:a.getAttribute(b,\"type\"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML=\"<input/>\",a.firstChild.setAttribute(\"value\",\"\"),\"\"===a.firstChild.getAttribute(\"value\")})||ja(\"value\",function(a,b,c){return c||\"input\"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute(\"disabled\")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[\":\"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\\w-]+)\\s*\\/?>(?:<\\/\\1>|)$/,y=/^.[^:#\\[\\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if(\"string\"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=\":not(\"+a+\")\"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if(\"string\"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+\" \"+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,\"string\"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,\"string\"==typeof a){if(e=\"<\"===a.charAt(0)&&\">\"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?\"undefined\"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||\"string\"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?\"string\"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,\"parentNode\")},parentsUntil:function(a,b,c){return u(a,\"parentNode\",c)},next:function(a){return F(a,\"nextSibling\")},prev:function(a){return F(a,\"previousSibling\")},nextAll:function(a){return u(a,\"nextSibling\")},prevAll:function(a){return u(a,\"previousSibling\")},nextUntil:function(a,b,c){return u(a,\"nextSibling\",c)},prevUntil:function(a,b,c){return u(a,\"previousSibling\",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,\"iframe\")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return\"Until\"!==a.slice(-5)&&(d=c),d&&\"string\"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a=\"string\"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:\"\")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&\"string\"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c=\"\",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[[\"resolve\",\"done\",n.Callbacks(\"once memory\"),\"resolved\"],[\"reject\",\"fail\",n.Callbacks(\"once memory\"),\"rejected\"],[\"notify\",\"progress\",n.Callbacks(\"memory\")]],c=\"pending\",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+\"With\"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+\"With\"](this===e?d:this,arguments),this},e[f[0]+\"With\"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler(\"ready\"),n(d).off(\"ready\"))))}});function J(){d.addEventListener?(d.removeEventListener(\"DOMContentLoaded\",K),a.removeEventListener(\"load\",K)):(d.detachEvent(\"onreadystatechange\",K),a.detachEvent(\"onload\",K))}function K(){(d.addEventListener||\"load\"===a.event.type||\"complete\"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),\"complete\"===d.readyState||\"loading\"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener(\"DOMContentLoaded\",K),a.addEventListener(\"load\",K);else{d.attachEvent(\"onreadystatechange\",K),a.attachEvent(\"onload\",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll(\"left\")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst=\"0\"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName(\"body\")[0],c&&c.style&&(b=d.createElement(\"div\"),e=d.createElement(\"div\"),e.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",c.appendChild(e).appendChild(b),\"undefined\"!=typeof b.style.zoom&&(b.style.cssText=\"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement(\"div\");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+\" \").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute(\"classid\")===b},N=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d=\"data-\"+b.replace(O,\"-$1\").toLowerCase();if(c=a.getAttribute(d),\"string\"==typeof c){try{c=\"true\"===c?!0:\"false\"===c?!1:\"null\"===c?null:+c+\"\"===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0;\n}return c}function Q(a){var b;for(b in a)if((\"data\"!==b||!n.isEmptyObject(a[b]))&&\"toJSON\"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||\"string\"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),\"object\"!=typeof b&&\"function\"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),\"string\"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(\" \")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{\"applet \":!0,\"embed \":!0,\"object \":\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,\"parsedAttrs\"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf(\"data-\")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,\"parsedAttrs\",!0)}return e}return\"object\"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||\"fx\")+\"queue\",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||\"fx\";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};\"inprogress\"===e&&(e=c.shift(),d--),e&&(\"fx\"===b&&c.unshift(\"inprogress\"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+\"queueHooks\";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks(\"once memory\").add(function(){n._removeData(a,b+\"queue\"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return\"string\"!=typeof a&&(b=a,a=\"fx\",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),\"fx\"===a&&\"inprogress\"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||\"fx\",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};\"string\"!=typeof a&&(b=a,a=void 0),a=a||\"fx\";while(g--)c=n._data(f[g],a+\"queueHooks\"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName(\"body\")[0],c&&c.style?(b=d.createElement(\"div\"),e=d.createElement(\"div\"),e.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",c.appendChild(e).appendChild(b),\"undefined\"!=typeof b.style.zoom&&(b.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1\",b.appendChild(d.createElement(\"div\")).style.width=\"5px\",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,U=new RegExp(\"^(?:([+-])=|)(\"+T+\")([a-z%]*)$\",\"i\"),V=[\"Top\",\"Right\",\"Bottom\",\"Left\"],W=function(a,b){return a=b||a,\"none\"===n.css(a,\"display\")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,\"\")},i=h(),j=c&&c[3]||(n.cssNumber[b]?\"\":\"px\"),k=(n.cssNumber[b]||\"px\"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||\".5\",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if(\"object\"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\\w:-]+)/,_=/^$|\\/(?:java|ecma)script/i,aa=/^\\s+/,ba=\"abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video\";function ca(a){var b=ba.split(\"|\"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement(\"div\"),b=d.createDocumentFragment(),c=d.createElement(\"input\");a.innerHTML=\" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName(\"tbody\").length,l.htmlSerialize=!!a.getElementsByTagName(\"link\").length,l.html5Clone=\"<:nav></:nav>\"!==d.createElement(\"nav\").cloneNode(!0).outerHTML,c.type=\"checkbox\",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML=\"<textarea>x</textarea>\",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement(\"input\"),c.setAttribute(\"type\",\"radio\"),c.setAttribute(\"checked\",\"checked\"),c.setAttribute(\"name\",\"t\"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,\"<select multiple='multiple'>\",\"</select>\"],legend:[1,\"<fieldset>\",\"</fieldset>\"],area:[1,\"<map>\",\"</map>\"],param:[1,\"<object>\",\"</object>\"],thead:[1,\"<table>\",\"</table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],col:[2,\"<table><tbody></tbody><colgroup>\",\"</colgroup></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:l.htmlSerialize?[0,\"\",\"\"]:[1,\"X<div>\",\"</div>\"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f=\"undefined\"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||\"*\"):\"undefined\"!=typeof a.querySelectorAll?a.querySelectorAll(b||\"*\"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,\"globalEval\",!b||n._data(b[d],\"globalEval\"))}var ga=/<|&#?\\w+;/,ha=/<tbody/i;function ia(a){Z.test(a.type)&&(a.defaultChecked=a.checked)}function ja(a,b,c,d,e){for(var f,g,h,i,j,k,m,o=a.length,p=ca(b),q=[],r=0;o>r;r++)if(g=a[r],g||0===g)if(\"object\"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement(\"div\")),j=($.exec(g)||[\"\",\"\"])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g=\"table\"!==j||ha.test(g)?\"<table>\"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],\"tbody\")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent=\"\";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,\"input\"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),\"script\"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||\"\")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement(\"div\");for(b in{submit:!0,change:!0,focusin:!0})c=\"on\"+b,(l[b]=c in a)||(e.setAttribute(c,\"t\"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if(\"object\"==typeof b){\"string\"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&(\"string\"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return\"undefined\"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||\"\").match(G)||[\"\"],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||\"\").split(\".\").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(\".\")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent(\"on\"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||\"\").match(G)||[\"\"],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||\"\").split(\".\").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp(\"(^|\\\\.)\"+p.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&(\"**\"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,\"events\"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,\"type\")?b.type:b,r=k.call(b,\"namespace\")?b.namespace.split(\".\"):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(\".\")>-1&&(r=q.split(\".\"),q=r.shift(),r.sort()),h=q.indexOf(\":\")<0&&\"on\"+q,b=b[n.expando]?b:new n.Event(q,\"object\"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join(\".\"),b.rnamespace=b.namespace?new RegExp(\"(^|\\\\.)\"+r.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,\"events\")||{})[b.type]&&n._data(i,\"handle\"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,\"events\")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(\"click\"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||\"click\"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+\" \",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ma.test(f)?this.mouseHooks:la.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=g.srcElement||d),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,h.filter?h.filter(a,g):a},props:\"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),fixHooks:{},keyHooks:{props:\"char charCode key keyCode\".split(\" \"),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:\"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),filter:function(a,b){var c,e,f,g=b.button,h=b.fromElement;return null==a.pageX&&null!=b.clientX&&(e=a.target.ownerDocument||d,f=e.documentElement,c=e.body,a.pageX=b.clientX+(f&&f.scrollLeft||c&&c.scrollLeft||0)-(f&&f.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(f&&f.scrollTop||c&&c.scrollTop||0)-(f&&f.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&h&&(a.relatedTarget=h===a.target?b.toElement:h),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ra()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:\"focusin\"},blur:{trigger:function(){return this===ra()&&this.blur?(this.blur(),!1):void 0},delegateType:\"focusout\"},click:{trigger:function(){return n.nodeName(this,\"input\")&&\"checkbox\"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,\"a\")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=d.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)}:function(a,b,c){var d=\"on\"+b;a.detachEvent&&(\"undefined\"==typeof a[d]&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?pa:qa):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:qa,isPropagationStopped:qa,isImmediatePropagationStopped:qa,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=pa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=pa,a&&!this.isSimulated&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=pa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submit||(n.event.special.submit={setup:function(){return n.nodeName(this,\"form\")?!1:void n.event.add(this,\"click._submit keypress._submit\",function(a){var b=a.target,c=n.nodeName(b,\"input\")||n.nodeName(b,\"button\")?n.prop(b,\"form\"):void 0;c&&!n._data(c,\"submit\")&&(n.event.add(c,\"submit._submit\",function(a){a._submitBubble=!0}),n._data(c,\"submit\",!0))})},postDispatch:function(a){a._submitBubble&&(delete a._submitBubble,this.parentNode&&!a.isTrigger&&n.event.simulate(\"submit\",this.parentNode,a))},teardown:function(){return n.nodeName(this,\"form\")?!1:void n.event.remove(this,\"._submit\")}}),l.change||(n.event.special.change={setup:function(){return ka.test(this.nodeName)?(\"checkbox\"!==this.type&&\"radio\"!==this.type||(n.event.add(this,\"propertychange._change\",function(a){\"checked\"===a.originalEvent.propertyName&&(this._justChanged=!0)}),n.event.add(this,\"click._change\",function(a){this._justChanged&&!a.isTrigger&&(this._justChanged=!1),n.event.simulate(\"change\",this,a)})),!1):void n.event.add(this,\"beforeactivate._change\",function(a){var b=a.target;ka.test(b.nodeName)&&!n._data(b,\"change\")&&(n.event.add(b,\"change._change\",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate(\"change\",this.parentNode,a)}),n._data(b,\"change\",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||\"radio\"!==b.type&&\"checkbox\"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,\"._change\"),!ka.test(this.nodeName)}}),l.focusin||n.each({focus:\"focusin\",blur:\"focusout\"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d){return sa(this,a,b,c,d)},one:function(a,b,c,d){return sa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+\".\"+d.namespace:d.origType,d.selector,d.handler),this;if(\"object\"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&\"function\"!=typeof b||(c=b,b=void 0),c===!1&&(c=qa),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ta=/ jQuery\\d+=\"(?:null|\\d+)\"/g,ua=new RegExp(\"<(?:\"+ba+\")[\\\\s/>]\",\"i\"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:-]+)[^>]*)\\/>/gi,wa=/<script|<style|<link/i,xa=/checked\\s*(?:[^=]|=\\s*.checked.)/i,ya=/^true\\/(.*)/,za=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement(\"div\"));function Ca(a,b){return n.nodeName(a,\"table\")&&n.nodeName(11!==b.nodeType?b:b.firstChild,\"tr\")?a.getElementsByTagName(\"tbody\")[0]||a.appendChild(a.ownerDocument.createElement(\"tbody\")):a}function Da(a){return a.type=(null!==n.find.attr(a,\"type\"))+\"/\"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute(\"type\"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}\"script\"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):\"object\"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):\"input\"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):\"option\"===c?b.defaultSelected=b.selected=a.defaultSelected:\"input\"!==c&&\"textarea\"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&\"string\"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,\"script\"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,\"script\"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||\"\")&&!n._data(g,\"globalEval\")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||\"\").replace(za,\"\")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,\"script\")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,\"<$1></$2>\")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test(\"<\"+a.nodeName+\">\")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,\"script\"),d.length>0&&fa(d,!i&&ea(a,\"script\")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||\"undefined\"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,\"select\")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,\"\"):void 0;if(\"string\"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||[\"\",\"\"])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:\"block\",BODY:\"block\"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],\"display\");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),\"none\"!==c&&c||(Ja=(Ja||n(\"<iframe frameborder='0' width='0' height='0'/>\")).appendTo(b.documentElement),b=(Ja[0].contentWindow||Ja[0].contentDocument).document,b.write(),b.close(),c=La(a,b),Ja.detach()),Ka[a]=c),c}var Na=/^margin/,Oa=new RegExp(\"^(\"+T+\")(?!px)[a-z%]+$\",\"i\"),Pa=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Qa=d.documentElement;!function(){var b,c,e,f,g,h,i=d.createElement(\"div\"),j=d.createElement(\"div\");if(j.style){j.style.cssText=\"float:left;opacity:.5\",l.opacity=\"0.5\"===j.style.opacity,l.cssFloat=!!j.style.cssFloat,j.style.backgroundClip=\"content-box\",j.cloneNode(!0).style.backgroundClip=\"\",l.clearCloneStyle=\"content-box\"===j.style.backgroundClip,i=d.createElement(\"div\"),i.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",j.innerHTML=\"\",i.appendChild(j),l.boxSizing=\"\"===j.style.boxSizing||\"\"===j.style.MozBoxSizing||\"\"===j.style.WebkitBoxSizing,n.extend(l,{reliableHiddenOffsets:function(){return null==b&&k(),f},boxSizingReliable:function(){return null==b&&k(),e},pixelMarginRight:function(){return null==b&&k(),c},pixelPosition:function(){return null==b&&k(),b},reliableMarginRight:function(){return null==b&&k(),g},reliableMarginLeft:function(){return null==b&&k(),h}});function k(){var k,l,m=d.documentElement;m.appendChild(i),j.style.cssText=\"-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",b=e=h=!1,c=g=!0,a.getComputedStyle&&(l=a.getComputedStyle(j),b=\"1%\"!==(l||{}).top,h=\"2px\"===(l||{}).marginLeft,e=\"4px\"===(l||{width:\"4px\"}).width,j.style.marginRight=\"50%\",c=\"4px\"===(l||{marginRight:\"4px\"}).marginRight,k=j.appendChild(d.createElement(\"div\")),k.style.cssText=j.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0\",k.style.marginRight=k.style.width=\"0\",j.style.width=\"1px\",g=!parseFloat((a.getComputedStyle(k)||{}).marginRight),j.removeChild(k)),j.style.display=\"none\",f=0===j.getClientRects().length,f&&(j.style.display=\"\",j.innerHTML=\"<table><tr><td></td><td>t</td></tr></table>\",j.childNodes[0].style.borderCollapse=\"separate\",k=j.getElementsByTagName(\"td\"),k[0].style.cssText=\"margin:0;border:0;padding:0;display:none\",f=0===k[0].offsetHeight,f&&(k[0].style.display=\"\",k[1].style.display=\"none\",f=0===k[0].offsetHeight)),m.removeChild(i)}}}();var Ra,Sa,Ta=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ra=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c.getPropertyValue(b)||c[b]:void 0,\"\"!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Oa.test(g)&&Na.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f),void 0===g?g:g+\"\"}):Qa.currentStyle&&(Ra=function(a){return a.currentStyle},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Oa.test(g)&&!Ta.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left=\"fontSize\"===b?\"1em\":g,g=h.pixelLeft+\"px\",h.left=d,f&&(e.left=f)),void 0===g?g:g+\"\"||\"auto\"});function Ua(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Va=/alpha\\([^)]*\\)/i,Wa=/opacity\\s*=\\s*([^)]*)/i,Xa=/^(none|table(?!-c[ea]).+)/,Ya=new RegExp(\"^(\"+T+\")(.*)$\",\"i\"),Za={position:\"absolute\",visibility:\"hidden\",display:\"block\"},$a={letterSpacing:\"0\",fontWeight:\"400\"},_a=[\"Webkit\",\"O\",\"Moz\",\"ms\"],ab=d.createElement(\"div\").style;function bb(a){if(a in ab)return a;var b=a.charAt(0).toUpperCase()+a.slice(1),c=_a.length;while(c--)if(a=_a[c]+b,a in ab)return a}function cb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,\"olddisplay\"),c=d.style.display,b?(f[g]||\"none\"!==c||(d.style.display=\"\"),\"\"===d.style.display&&W(d)&&(f[g]=n._data(d,\"olddisplay\",Ma(d.nodeName)))):(e=W(d),(c&&\"none\"!==c||!e)&&n._data(d,\"olddisplay\",e?c:n.css(d,\"display\"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&\"none\"!==d.style.display&&\"\"!==d.style.display||(d.style.display=b?f[g]||\"\":\"none\"));return a}function db(a,b,c){var d=Ya.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||\"px\"):b}function eb(a,b,c,d,e){for(var f=c===(d?\"border\":\"content\")?4:\"width\"===b?1:0,g=0;4>f;f+=2)\"margin\"===c&&(g+=n.css(a,c+V[f],!0,e)),d?(\"content\"===c&&(g-=n.css(a,\"padding\"+V[f],!0,e)),\"margin\"!==c&&(g-=n.css(a,\"border\"+V[f]+\"Width\",!0,e))):(g+=n.css(a,\"padding\"+V[f],!0,e),\"padding\"!==c&&(g+=n.css(a,\"border\"+V[f]+\"Width\",!0,e)));return g}function fb(a,b,c){var d=!0,e=\"width\"===b?a.offsetWidth:a.offsetHeight,f=Ra(a),g=l.boxSizing&&\"border-box\"===n.css(a,\"boxSizing\",!1,f);if(0>=e||null==e){if(e=Sa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Oa.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+eb(a,b,c||(g?\"border\":\"content\"),d,f)+\"px\"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Sa(a,\"opacity\");return\"\"===c?\"1\":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\"float\":l.cssFloat?\"cssFloat\":\"styleFloat\"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&\"get\"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,\"string\"===f&&(e=U.exec(c))&&e[1]&&(c=X(a,b,e),f=\"number\"),null!=c&&c===c&&(\"number\"===f&&(c+=e&&e[3]||(n.cssNumber[h]?\"\":\"px\")),l.clearCloneStyle||\"\"!==c||0!==b.indexOf(\"background\")||(i[b]=\"inherit\"),!(g&&\"set\"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&\"get\"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Sa(a,b,d)),\"normal\"===f&&b in $a&&(f=$a[b]),\"\"===c||c?(e=parseFloat(f),c===!0||isFinite(e)?e||0:f):f}}),n.each([\"height\",\"width\"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Xa.test(n.css(a,\"display\"))&&0===a.offsetWidth?Pa(a,Za,function(){return fb(a,b,d)}):fb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ra(a);return db(a,c,d?eb(a,b,d,l.boxSizing&&\"border-box\"===n.css(a,\"boxSizing\",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Wa.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||\"\")?.01*parseFloat(RegExp.$1)+\"\":b?\"1\":\"\"},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?\"alpha(opacity=\"+100*b+\")\":\"\",f=d&&d.filter||c.filter||\"\";c.zoom=1,(b>=1||\"\"===b)&&\"\"===n.trim(f.replace(Va,\"\"))&&c.removeAttribute&&(c.removeAttribute(\"filter\"),\"\"===b||d&&!d.filter)||(c.filter=Va.test(f)?f.replace(Va,e):f+\" \"+e)}}),n.cssHooks.marginRight=Ua(l.reliableMarginRight,function(a,b){return b?Pa(a,{display:\"inline-block\"},Sa,[a,\"marginRight\"]):void 0}),n.cssHooks.marginLeft=Ua(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Sa(a,\"marginLeft\"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{\n marginLeft:0},function(){return a.getBoundingClientRect().left}):0))+\"px\":void 0}),n.each({margin:\"\",padding:\"\",border:\"Width\"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f=\"string\"==typeof c?c.split(\" \"):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return\"boolean\"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?\"\":\"px\")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,\"\"),b&&\"auto\"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:\"swing\"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d[\"margin\"+c]=d[\"padding\"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners[\"*\"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,\"fxshow\");c.queue||(h=n._queueHooks(a,\"fx\"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,\"fx\").length||h.empty.fire()})})),1===a.nodeType&&(\"height\"in b||\"width\"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,\"display\"),k=\"none\"===j?n._data(a,\"olddisplay\")||Ma(a.nodeName):j,\"inline\"===k&&\"none\"===n.css(a,\"float\")&&(l.inlineBlockNeedsLayout&&\"inline\"!==Ma(a.nodeName)?p.zoom=1:p.display=\"inline-block\")),c.overflow&&(p.overflow=\"hidden\",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||\"toggle\"===e,e===(q?\"hide\":\"show\")){if(\"show\"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))\"inline\"===(\"none\"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?\"hidden\"in r&&(q=r.hidden):r=n._data(a,\"fxshow\",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,\"fxshow\");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start=\"width\"===d||\"height\"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&\"expand\"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(pb(k,j.opts.specialEasing);g>f;f++)if(d=qb.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,nb,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(qb,{tweeners:{\"*\":[function(a,b){var c=this.createTween(a,b);return X(c.elem,a,U.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=[\"*\"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],qb.tweeners[c]=qb.tweeners[c]||[],qb.tweeners[c].unshift(b)},prefilters:[ob],prefilter:function(a,b){b?qb.prefilters.unshift(a):qb.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&\"object\"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:\"number\"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue=\"fx\"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(W).css(\"opacity\",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=qb(this,n.extend({},a),f);(e||n._data(this,\"finish\"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return\"string\"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||\"fx\",[]),this.each(function(){var b=!0,e=null!=a&&a+\"queueHooks\",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&kb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||\"fx\"),this.each(function(){var b,c=n._data(this),d=c[a+\"queue\"],e=c[a+\"queueHooks\"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each([\"toggle\",\"show\",\"hide\"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||\"boolean\"==typeof a?c.apply(this,arguments):this.animate(mb(b,!0),a,d,e)}}),n.each({slideDown:mb(\"show\"),slideUp:mb(\"hide\"),slideToggle:mb(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(hb=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),hb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ib||(ib=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(ib),ib=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||\"fx\",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a,b=d.createElement(\"input\"),c=d.createElement(\"div\"),e=d.createElement(\"select\"),f=e.appendChild(d.createElement(\"option\"));c=d.createElement(\"div\"),c.setAttribute(\"className\",\"t\"),c.innerHTML=\" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",a=c.getElementsByTagName(\"a\")[0],b.setAttribute(\"type\",\"checkbox\"),c.appendChild(b),a=c.getElementsByTagName(\"a\")[0],a.style.cssText=\"top:1px\",l.getSetAttribute=\"t\"!==c.className,l.style=/top/.test(a.getAttribute(\"style\")),l.hrefNormalized=\"/a\"===a.getAttribute(\"href\"),l.checkOn=!!b.value,l.optSelected=f.selected,l.enctype=!!d.createElement(\"form\").enctype,e.disabled=!0,l.optDisabled=!f.disabled,b=d.createElement(\"input\"),b.setAttribute(\"value\",\"\"),l.input=\"\"===b.getAttribute(\"value\"),b.value=\"t\",b.setAttribute(\"type\",\"radio\"),l.radioValue=\"t\"===b.value}();var rb=/\\r/g,sb=/[\\x20\\t\\r\\n\\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e=\"\":\"number\"==typeof e?e+=\"\":n.isArray(e)&&(e=n.map(e,function(a){return null==a?\"\":a+\"\"})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&\"set\"in b&&void 0!==b.set(this,e,\"value\")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&\"get\"in b&&void 0!==(c=b.get(e,\"value\"))?c:(c=e.value,\"string\"==typeof c?c.replace(rb,\"\"):null==c?\"\":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,\"value\");return null!=b?b:n.trim(n.text(a)).replace(sb,\" \")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f=\"select-one\"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute(\"disabled\"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,\"optgroup\"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>-1)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each([\"radio\",\"checkbox\"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute(\"value\")?\"on\":a.value})});var tb,ub,vb=n.expr.attrHandle,wb=/^(?:checked|selected)$/i,xb=l.getSetAttribute,yb=l.input;n.fn.extend({attr:function(a,b){return Y(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return\"undefined\"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ub:tb)),void 0!==c?null===c?void n.removeAttr(a,b):e&&\"set\"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+\"\"),c):e&&\"get\"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&\"radio\"===b&&n.nodeName(a,\"input\")){var c=a.value;return a.setAttribute(\"type\",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?yb&&xb||!wb.test(c)?a[d]=!1:a[n.camelCase(\"default-\"+c)]=a[d]=!1:n.attr(a,c,\"\"),a.removeAttribute(xb?c:d)}}),ub={set:function(a,b,c){return b===!1?n.removeAttr(a,c):yb&&xb||!wb.test(c)?a.setAttribute(!xb&&n.propFix[c]||c,c):a[n.camelCase(\"default-\"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\\w+/g),function(a,b){var c=vb[b]||n.find.attr;yb&&xb||!wb.test(b)?vb[b]=function(a,b,d){var e,f;return d||(f=vb[b],vb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,vb[b]=f),e}:vb[b]=function(a,b,c){return c?void 0:a[n.camelCase(\"default-\"+b)]?b.toLowerCase():null}}),yb&&xb||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,\"input\")?void(a.defaultValue=b):tb&&tb.set(a,b,c)}}),xb||(tb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+=\"\",\"value\"===c||b===a.getAttribute(c)?b:void 0}},vb.id=vb.name=vb.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&\"\"!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:tb.set},n.attrHooks.contenteditable={set:function(a,b,c){tb.set(a,\"\"===b?!1:b,c)}},n.each([\"width\",\"height\"],function(a,b){n.attrHooks[b]={set:function(a,c){return\"\"===c?(a.setAttribute(b,\"auto\"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+\"\"}});var zb=/^(?:input|select|textarea|button|object)$/i,Ab=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return Y(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&\"set\"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&\"get\"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,\"tabindex\");return b?parseInt(b,10):zb.test(a.nodeName)||Ab.test(a.nodeName)&&a.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),l.hrefNormalized||n.each([\"href\",\"src\"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype=\"encoding\");var Bb=/[\\t\\r\\n\\f]/g;function Cb(a){return n.attr(a,\"class\")||\"\"}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,Cb(this)))});if(\"string\"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(\" \"+e+\" \").replace(Bb,\" \")){g=0;while(f=b[g++])d.indexOf(\" \"+f+\" \")<0&&(d+=f+\" \");h=n.trim(d),e!==h&&n.attr(c,\"class\",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,Cb(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(\" \"+e+\" \").replace(Bb,\" \")){g=0;while(f=b[g++])while(d.indexOf(\" \"+f+\" \")>-1)d=d.replace(\" \"+f+\" \",\" \");h=n.trim(d),e!==h&&n.attr(c,\"class\",h)}}return this},toggleClass:function(a,b){var c=typeof a;return\"boolean\"==typeof b&&\"string\"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,Cb(this),b),b)}):this.each(function(){var b,d,e,f;if(\"string\"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&\"boolean\"!==c||(b=Cb(this),b&&n._data(this,\"__className__\",b),n.attr(this,\"class\",b||a===!1?\"\":n._data(this,\"__className__\")||\"\"))})},hasClass:function(a){var b,c,d=0;b=\" \"+a+\" \";while(c=this[d++])if(1===c.nodeType&&(\" \"+Cb(c)+\" \").replace(Bb,\" \").indexOf(b)>-1)return!0;return!1}}),n.each(\"blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu\".split(\" \"),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Db=a.location,Eb=n.now(),Fb=/\\?/,Gb=/(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+\"\");var c,d=null,e=n.trim(b+\"\");return e&&!n.trim(e.replace(Gb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,\"\")}))?Function(\"return \"+e)():n.error(\"Invalid JSON: \"+b)},n.parseXML=function(b){var c,d;if(!b||\"string\"!=typeof b)return null;try{a.DOMParser?(d=new a.DOMParser,c=d.parseFromString(b,\"text/xml\")):(c=new a.ActiveXObject(\"Microsoft.XMLDOM\"),c.async=\"false\",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName(\"parsererror\").length||n.error(\"Invalid XML: \"+b),c};var Hb=/#.*$/,Ib=/([?&])_=[^&]*/,Jb=/^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/gm,Kb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Lb=/^(?:GET|HEAD)$/,Mb=/^\\/\\//,Nb=/^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,Ob={},Pb={},Qb=\"*/\".concat(\"*\"),Rb=Db.href,Sb=Nb.exec(Rb.toLowerCase())||[];function Tb(a){return function(b,c){\"string\"!=typeof b&&(c=b,b=\"*\");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])\"+\"===d.charAt(0)?(d=d.slice(1)||\"*\",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Ub(a,b,c,d){var e={},f=a===Pb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return\"string\"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e[\"*\"]&&g(\"*\")}function Vb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Wb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while(\"*\"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader(\"Content-Type\"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+\" \"+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Xb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if(\"*\"===f)f=i;else if(\"*\"!==i&&i!==f){if(g=j[i+\" \"+f]||j[\"* \"+f],!g)for(e in j)if(h=e.split(\" \"),h[1]===f&&(g=j[i+\" \"+h[0]]||j[\"* \"+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a[\"throws\"])b=g(b);else try{b=g(b)}catch(l){return{state:\"parsererror\",error:g?l:\"No conversion from \"+i+\" to \"+f}}}return{state:\"success\",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Rb,type:\"GET\",isLocal:Kb.test(Sb[1]),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Qb,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":n.parseJSON,\"text xml\":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Vb(Vb(a,n.ajaxSettings),b):Vb(n.ajaxSettings,a)},ajaxPrefilter:Tb(Ob),ajaxTransport:Tb(Pb),ajax:function(b,c){\"object\"==typeof b&&(c=b,b=void 0),c=c||{};var d,e,f,g,h,i,j,k,l=n.ajaxSetup({},c),m=l.context||l,o=l.context&&(m.nodeType||m.jquery)?n(m):n.event,p=n.Deferred(),q=n.Callbacks(\"once memory\"),r=l.statusCode||{},s={},t={},u=0,v=\"canceled\",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!k){k={};while(b=Jb.exec(g))k[b[1].toLowerCase()]=b[2]}b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return j&&j.abort(b),y(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,l.url=((b||l.url||Rb)+\"\").replace(Hb,\"\").replace(Mb,Sb[1]+\"//\"),l.type=c.method||c.type||l.method||l.type,l.dataTypes=n.trim(l.dataType||\"*\").toLowerCase().match(G)||[\"\"],null==l.crossDomain&&(d=Nb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Sb[1]&&d[2]===Sb[2]&&(d[3]||(\"http:\"===d[1]?\"80\":\"443\"))===(Sb[3]||(\"http:\"===Sb[1]?\"80\":\"443\")))),l.data&&l.processData&&\"string\"!=typeof l.data&&(l.data=n.param(l.data,l.traditional)),Ub(Ob,l,c,w),2===u)return w;i=n.event&&l.global,i&&0===n.active++&&n.event.trigger(\"ajaxStart\"),l.type=l.type.toUpperCase(),l.hasContent=!Lb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Fb.test(f)?\"&\":\"?\")+l.data,delete l.data),l.cache===!1&&(l.url=Ib.test(f)?f.replace(Ib,\"$1_=\"+Eb++):f+(Fb.test(f)?\"&\":\"?\")+\"_=\"+Eb++)),l.ifModified&&(n.lastModified[f]&&w.setRequestHeader(\"If-Modified-Since\",n.lastModified[f]),n.etag[f]&&w.setRequestHeader(\"If-None-Match\",n.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&w.setRequestHeader(\"Content-Type\",l.contentType),w.setRequestHeader(\"Accept\",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(\"*\"!==l.dataTypes[0]?\", \"+Qb+\"; q=0.01\":\"\"):l.accepts[\"*\"]);for(e in l.headers)w.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,w,l)===!1||2===u))return w.abort();v=\"abort\";for(e in{success:1,error:1,complete:1})w[e](l[e]);if(j=Ub(Pb,l,c,w)){if(w.readyState=1,i&&o.trigger(\"ajaxSend\",[w,l]),2===u)return w;l.async&&l.timeout>0&&(h=a.setTimeout(function(){w.abort(\"timeout\")},l.timeout));try{u=1,j.send(s,y)}catch(x){if(!(2>u))throw x;y(-1,x)}}else y(-1,\"No Transport\");function y(b,c,d,e){var k,s,t,v,x,y=c;2!==u&&(u=2,h&&a.clearTimeout(h),j=void 0,g=e||\"\",w.readyState=b>0?4:0,k=b>=200&&300>b||304===b,d&&(v=Wb(l,w,d)),v=Xb(l,v,w,k),k?(l.ifModified&&(x=w.getResponseHeader(\"Last-Modified\"),x&&(n.lastModified[f]=x),x=w.getResponseHeader(\"etag\"),x&&(n.etag[f]=x)),204===b||\"HEAD\"===l.type?y=\"nocontent\":304===b?y=\"notmodified\":(y=v.state,s=v.data,t=v.error,k=!t)):(t=y,!b&&y||(y=\"error\",0>b&&(b=0))),w.status=b,w.statusText=(c||y)+\"\",k?p.resolveWith(m,[s,y,w]):p.rejectWith(m,[w,y,t]),w.statusCode(r),r=void 0,i&&o.trigger(k?\"ajaxSuccess\":\"ajaxError\",[w,l,k?s:t]),q.fireWith(m,[w,y]),i&&(o.trigger(\"ajaxComplete\",[w,l]),--n.active||n.event.trigger(\"ajaxStop\")))}return w},getJSON:function(a,b,c){return n.get(a,b,c,\"json\")},getScript:function(a,b){return n.get(a,void 0,b,\"script\")}}),n.each([\"get\",\"post\"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,\"throws\":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,\"body\")||n(this).replaceWith(this.childNodes)}).end()}});function Yb(a){return a.style&&a.style.display||n.css(a,\"display\")}function Zb(a){if(!n.contains(a.ownerDocument||d,a))return!0;while(a&&1===a.nodeType){if(\"none\"===Yb(a)||\"hidden\"===a.type)return!0;a=a.parentNode}return!1}n.expr.filters.hidden=function(a){return l.reliableHiddenOffsets()?a.offsetWidth<=0&&a.offsetHeight<=0&&!a.getClientRects().length:Zb(a)},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var $b=/%20/g,_b=/\\[\\]$/,ac=/\\r?\\n/g,bc=/^(?:submit|button|image|reset|file)$/i,cc=/^(?:input|select|textarea|keygen)/i;function dc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||_b.test(a)?d(a,e):dc(a+\"[\"+(\"object\"==typeof e&&null!=e?b:\"\")+\"]\",e,c,d)});else if(c||\"object\"!==n.type(b))d(a,b);else for(e in b)dc(a+\"[\"+e+\"]\",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?\"\":b,d[d.length]=encodeURIComponent(a)+\"=\"+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)dc(c,a[c],b,e);return d.join(\"&\").replace($b,\"+\")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,\"elements\");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(\":disabled\")&&cc.test(this.nodeName)&&!bc.test(a)&&(this.checked||!Z.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(ac,\"\\r\\n\")}}):{name:b.name,value:c.replace(ac,\"\\r\\n\")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return this.isLocal?ic():d.documentMode>8?hc():/^(get|post|head|put|delete|options)$/i.test(this.type)&&hc()||ic()}:hc;var ec=0,fc={},gc=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent(\"onunload\",function(){for(var a in fc)fc[a](void 0,!0)}),l.cors=!!gc&&\"withCredentials\"in gc,gc=l.ajax=!!gc,gc&&n.ajaxTransport(function(b){if(!b.crossDomain||l.cors){var c;return{send:function(d,e){var f,g=b.xhr(),h=++ec;if(g.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(f in b.xhrFields)g[f]=b.xhrFields[f];b.mimeType&&g.overrideMimeType&&g.overrideMimeType(b.mimeType),b.crossDomain||d[\"X-Requested-With\"]||(d[\"X-Requested-With\"]=\"XMLHttpRequest\");for(f in d)void 0!==d[f]&&g.setRequestHeader(f,d[f]+\"\");g.send(b.hasContent&&b.data||null),c=function(a,d){var f,i,j;if(c&&(d||4===g.readyState))if(delete fc[h],c=void 0,g.onreadystatechange=n.noop,d)4!==g.readyState&&g.abort();else{j={},f=g.status,\"string\"==typeof g.responseText&&(j.text=g.responseText);try{i=g.statusText}catch(k){i=\"\"}f||!b.isLocal||b.crossDomain?1223===f&&(f=204):f=j.text?200:404}j&&e(f,i,j,g.getAllResponseHeaders())},b.async?4===g.readyState?a.setTimeout(c):g.onreadystatechange=fc[h]=c:c()},abort:function(){c&&c(void 0,!0)}}}});function hc(){try{return new a.XMLHttpRequest}catch(b){}}function ic(){try{return new a.ActiveXObject(\"Microsoft.XMLHTTP\")}catch(b){}}n.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter(\"script\",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type=\"GET\",a.global=!1)}),n.ajaxTransport(\"script\",function(a){if(a.crossDomain){var b,c=d.head||n(\"head\")[0]||d.documentElement;return{send:function(e,f){b=d.createElement(\"script\"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||f(200,\"success\"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var jc=[],kc=/(=)\\?(?=&|$)|\\?\\?/;n.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var a=jc.pop()||n.expando+\"_\"+Eb++;return this[a]=!0,a}}),n.ajaxPrefilter(\"json jsonp\",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(kc.test(b.url)?\"url\":\"string\"==typeof b.data&&0===(b.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&kc.test(b.data)&&\"data\");return h||\"jsonp\"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(kc,\"$1\"+e):b.jsonp!==!1&&(b.url+=(Fb.test(b.url)?\"&\":\"?\")+b.jsonp+\"=\"+e),b.converters[\"script json\"]=function(){return g||n.error(e+\" was not called\"),g[0]},b.dataTypes[0]=\"json\",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,jc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),\"script\"):void 0}),n.parseHTML=function(a,b,c){if(!a||\"string\"!=typeof a)return null;\"boolean\"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ja([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var lc=n.fn.load;n.fn.load=function(a,b,c){if(\"string\"!=typeof a&&lc)return lc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(\" \");return h>-1&&(d=n.trim(a.slice(h,a.length)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&\"object\"==typeof b&&(e=\"POST\"),g.length>0&&n.ajax({url:a,type:e||\"GET\",dataType:\"html\",data:b}).done(function(a){f=arguments,g.html(d?n(\"<div>\").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},n.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function mc(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,\"position\"),l=n(a),m={};\"static\"===k&&(a.style.position=\"relative\"),h=l.offset(),f=n.css(a,\"top\"),i=n.css(a,\"left\"),j=(\"absolute\"===k||\"fixed\"===k)&&n.inArray(\"auto\",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),\"using\"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(\"undefined\"!=typeof e.getBoundingClientRect&&(d=e.getBoundingClientRect()),c=mc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return\"fixed\"===n.css(d,\"position\")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],\"html\")||(c=a.offset()),c.top+=n.css(a[0],\"borderTopWidth\",!0),c.left+=n.css(a[0],\"borderLeftWidth\",!0)),{top:b.top-c.top-n.css(d,\"marginTop\",!0),left:b.left-c.left-n.css(d,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&!n.nodeName(a,\"html\")&&\"static\"===n.css(a,\"position\"))a=a.offsetParent;return a||Qa})}}),n.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return Y(this,function(a,d,e){var f=mc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each([\"top\",\"left\"],function(a,b){n.cssHooks[b]=Ua(l.pixelPosition,function(a,c){return c?(c=Sa(a,b),Oa.test(c)?n(a).position()[b]+\"px\":c):void 0})}),n.each({Height:\"height\",Width:\"width\"},function(a,b){n.each({\n padding:\"inner\"+a,content:b,\"\":\"outer\"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||\"boolean\"!=typeof d),g=c||(d===!0||e===!0?\"margin\":\"border\");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement[\"client\"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body[\"scroll\"+a],e[\"scroll\"+a],b.body[\"offset\"+a],e[\"offset\"+a],e[\"client\"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,\"**\"):this.off(b,a||\"**\",c)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});\n",
|
|
39
|
-
"'use strict';\nif ( typeof(module) !== 'undefined' && module.exports ) {\n var lib = require('../../index');\n}\n\n/**\n * Collection cLass\n * Allows you to handle your own collections as you would normaly with mongodb\n * Dependencies :\n * - lib/merge\n * - uuid\n *\n *\n * @param {array} collection\n * @param {object} [options]\n *\n * @returns {object} instance\n * \n * Collection.length will return result length : dont't use .count() which is going to include functions to the count\n *\n * Collection::find\n * @param {object} filter\n * eg.: { uid: 'someUID' }\n * eg.: { type: 'not null', country: 'France' } // `AND` clause\n * NB.: To filter `not empty`, use { type: '!=\"\"' }\n * eg.: { country: 'The Hashemite Kingdom of Jordan' }, { country: 'Libanon'} // `OR` clause \n * eg.: { 'obj.prop': true }\n * eg.: { 'contacts[*].name': 'Doe' } // `WITHIN` (array|collection) clause\n * eg.: { lastUpdate: '>= 2016-12-01T00:00:00' } // also available for date comparison `=`, `<`, `>`\n * eg.: { activity: null }\n * eg.: { isActive: false }\n *\n * @returns {array} result\n *\n * Collection::findOne\n * @param {object} filter\n * @returns {object|array|string} result\n *\n * Collection::update\n * @param {object} filter\n * @param {object} set\n *\n * @returns {array} result\n * rasult.toRaw() will give result without chaining & _uuid\n *\n * */\nfunction Collection(content, options) {\n\n var isGFFCtx = ( ( typeof(module) !== 'undefined' ) && module.exports ) ? false : true;\n var uuid = (isGFFCtx) ? require('vendor/uuid') : require('uuid');\n var merge = (isGFFCtx) ? require('utils/merge') : require('../../../lib/merge');\n\n // defined search option rules\n var searchOptionRules = {\n isCaseSensitive: {\n false: {\n re: '^%s$',\n modifiers: 'i'\n },\n true: {\n re: '^%s$'\n }\n }\n };\n var withOrClause = false;\n var notInSearchModeEnabled = false;\n \n var localSearchOptions = null;\n \n var defaultOptions = {\n useLocalStorage: false,\n locale: 'en', // TODO - get settigs.region, or user.region\n searchOptionRules: searchOptionRules\n };\n \n \n \n options = (typeof(options) == 'object') ? merge(options, defaultOptions) : defaultOptions;\n\n var keywords = ['not null']; // TODO - null, exists (`true` if property is defined)\n var tryEval = function(condition) {\n try {\n return eval(condition);\n } catch(err) {\n throw new Error('Could not evaluate condition `'+ condition +'`.\\n' + err.stack );\n }\n }\n\n if (typeof(content) == 'undefined' || content == '' || content == null)\n content = [];\n\n if ( !Array.isArray(content) )\n throw new Error('`new Collection([content] [, options] )`: `content` argument must be an Array !');\n\n content = (content) ? JSON.clone(content) : []; // original content -> not to be touched\n \n // Indexing : uuids are generated for each entry\n var searchIndex = [], idx = 0;\n for (var entry = 0, entryLen = content.length; entry < entryLen; ++entry) {\n if (!content[entry]) {\n content[entry] = {};\n }\n content[entry]._uuid = uuid.v4();\n // To avoid duplicate entries\n searchIndex[idx] = content[entry]._uuid;\n ++idx;\n }\n\n var instance = content; \n /**\n * Set local search option for the current collection method call\n * \n * eg.: \n * var recCollection = new Collection(arrayCollection);\n * var rec = recCollection\n * .setSearchOption('name', 'isCaseSensitive', false)\n * .find({ city: 'cap Town' });\n * \n * eg.:\n * var recCollection = new Collection(arrayCollection);\n * var searchOptions = {\n * name: {\n * isCaseSensitive: false\n * }\n * };\n * var rec = recCollection\n * .setSearchOption(searchOptions)\n * .find({ city: 'cap Town' }); * \n * \n * @param {object|string} searchOptionObject or searchOptionTargetedProperty\n * @param {string} [searchRule]\n * @param {boolean} [searchRuleValue] - true to enable, false to disabled\n * \n * @returns {object} instance with local search options\n */\n instance['setSearchOption'] = function() {\n \n if (!arguments.length)\n throw new Error('searchOption cannot be left blank');\n \n if (arguments.length > 3 || arguments.length < 3 && arguments.length > 1)\n throw new Error('argument length mismatch');\n \n var i = 0\n , len = arguments.length\n ;\n \n if (arguments.length == 1) {\n if ( typeof(arguments[0]) != 'object' )\n throw new Error('searchOption must be an object');\n \n for (var prop in arguments[0]) {\n if ( typeof(searchOptionRules[prop]) == 'undefined' )\n throw new Error(arguments[1] + ' is not an allowed searchOption !');\n }\n \n localSearchOptions = arguments[0];\n } else {\n \n if ( !localSearchOptions )\n localSearchOptions = {};\n \n for (; i < len; ++i) { \n if ( typeof(searchOptionRules[arguments[1]]) == 'undefined' )\n throw new Error(arguments[1] + ' is not an allowed searchOption !');\n \n if (typeof(localSearchOptions[arguments[0]]) == 'undefined')\n localSearchOptions[arguments[0]] = {};\n \n if ( /true|false/i.test(arguments[2]) ) {\n localSearchOptions[arguments[0]][arguments[1]] = /true/i.test(arguments[2]) ? true : false\n } else {\n localSearchOptions[arguments[0]][arguments[1]] = arguments[2]\n } \n }\n } \n \n return instance\n }\n\n \n instance['find'] = function() {\n // reset \n withOrClause = false;\n \n if ( typeof(arguments[arguments.length-1]) == 'boolean' ) {\n withOrClause = arguments[arguments.length-1];\n delete arguments[arguments.length-1];\n --arguments.length;\n }\n\n var filtersStr = null;\n var filters = null;\n var filtersCount = null;\n try {\n filtersStr = JSON.stringify(arguments);\n filters = JSON.parse(filtersStr);\n filtersCount = filters.count();\n } catch( filtersError) {\n throw new Error('filter must be an object\\n'+ filtersError.stack); \n } \n \n if ( typeof(filters) != 'undefined' && filtersCount > 0 ) {\n \n if (filtersCount > 1) {\n withOrClause = true; \n }\n // checking filter : this should be forbidden -> { type: 'red', type: 'orange'}\n // var filtersFields = null;\n // for (let f = 0, fLen = filters.count(); f < fLen; f++) {\n // filtersFields = {};\n // for (let fField in filters[f]) {\n // if ( typeof(filtersFields[ fField ]) != 'undefined' ) {\n // throw new Error('Filter field can only be defined once inside a filter object !\\n`Field '+ fField +'` is already defined : '+ filters[f])\n // }\n // filtersFields[ fField ] = true;\n // }\n // }\n \n var filter = null\n , condition = null\n , i = 0\n //, tmpContent = ( Array.isArray(this) && !withOrClause) ? this : JSON.clone(content)\n , tmpContent = ( Array.isArray(this) ) ? this : JSON.clone(content)\n , resultObj = {}\n , result = []\n , localeLowerCase = ''\n , re = null\n , field = null\n , fieldWithin = null\n , value = null\n , searchOptions = localSearchOptions\n , searchOptionRules = options.searchOptionRules\n ;\n\n var matched = null\n , filterIsArray = null\n , searchResult = [];\n \n /**\n * Regular Search\n * @param {object} filter \n * @param {string} field \n * @param {strine|number|date} _content \n * @param {number} matched \n */\n var search = function(filter, field, _content, matched, searchOptionRules) {\n var reValidCount = null, searchOptCount = null;\n if (filter === null && _content === null) { // null case\n\n ++matched;\n\n } else if (\n filter \n && keywords.indexOf(localeLowerCase) > -1 \n && localeLowerCase == 'not null' \n && typeof(_content) != 'undefined' \n && typeof(_content) !== 'object' \n && _content != 'null' \n && _content != 'undefined'\n ) {\n \n if (result.indexOf(_content) < 0) {\n ++matched;\n }\n\n } else if ( \n typeof(_content) != 'undefined' \n && typeof(_content) !== 'object' \n && /(<|>|=)/.test(filter) \n && !/undefined|function/.test(typeof(_content))\n ) { // with operations\n let originalFilter = filter;\n let condition = _content + filter;\n if ( typeof(filter) == 'string' && typeof(_content) == 'string' ) {\n let comparedValue = filter.replace(/^(<=|>=|!==|!=|===|!==)/g, '');\n if ( typeof(_content) == 'string' && !/^\\\"(.*)\\\"$/.test(comparedValue) ) {\n filter = filter.replace(comparedValue, '\\\"'+ comparedValue + '\\\"');\n }\n condition = '\\\"'+_content+'\\\"' + filter;\n // restoring in case of datetime eval\n filter = originalFilter;\n }\n \n // looking for a datetime ?\n if (\n /(\\d{4})\\-(\\d{2})\\-(\\d{2})(\\s+|T)(\\d{2}):(\\d{2}):(\\d{2})/.test(_content)\n && /(\\d{4})\\-(\\d{2})\\-(\\d{2})(\\s+|T)(\\d{2}):(\\d{2}):(\\d{2})/.test(filter)\n ) {\n\n if (tryEval(_content.replace(/(\\d{4})\\-(\\d{2})\\-(\\d{2})(\\s+|T)(\\d{2}):(\\d{2}):(\\d{2})/, 'new Date(\"$&\")') + filter.replace(/(\\d{4})\\-(\\d{2})\\-(\\d{2})(\\s+|T)(\\d{2}):(\\d{2}):(\\d{2})/, 'new Date(\"$&\")'))) {\n ++matched;\n }\n\n } else if (tryEval(condition)) {\n ++matched;\n }\n\n } else if ( \n typeof(_content) != 'undefined' \n && typeof(_content) !== 'object' \n && _content === filter\n && !searchOptions\n ||\n typeof(_content) != 'undefined' \n && typeof(_content) !== 'object' \n && _content === filter\n && typeof(searchOptions[field]) == 'undefined'\n ) {\n\n ++matched;\n } else if ( \n typeof(_content) != 'undefined' \n && typeof(_content) !== 'object' \n && searchOptions\n && typeof(searchOptions[field]) != 'undefined'\n ) {\n \n reValidCount = 0;\n searchOptCount = searchOptions[field].count();\n for ( var rule in searchOptions[field]) {\n searchOptionRules[rule][searchOptions[field][rule]].re = searchOptionRules[rule][searchOptions[field][rule]].re.replace(/\\%s/, filter);\n \n if (searchOptionRules[rule][searchOptions[field][rule]].modifiers) {\n re = new RegExp(searchOptionRules[rule][searchOptions[field][rule]].re, searchOptionRules[rule][searchOptions[field][rule]].modifiers); \n } else {\n re = new RegExp(searchOptionRules[rule][searchOptions[field][rule]].re);\n }\n \n if ( re.test(_content) ) {\n ++reValidCount\n }\n }\n \n if (reValidCount == searchOptCount) {\n ++matched; \n }\n }\n\n return {\n matched: matched\n };\n }\n\n var searchThroughProp = function(filter, f, _content, matched) {\n\n var field = f.split(/\\./g);\n field = field[field.length - 1];\n re = new RegExp('(\"' + field + '\":\\\\w+)');\n \n var value = null;\n \n try {\n if ( _content )\n value = eval('_content.'+f);\n } catch (err) {\n // Nothing to do\n // means that the field is not available in the collection\n } \n \n \n\n if (value /** && value.length > 0*/) {\n if ( Array.isArray(value) )\n value = value[1].split(/:/)[1];\n else if ( typeof(value) == 'string' && /\\:/.test(value) )\n value = value.split(/:/)[1];\n \n \n if (/(<|>|=)/.test(filter)) {\n\n // looking for a datetime ?\n if (\n /(\\d{4})\\-(\\d{2})\\-(\\d{2})(\\s+|T)(\\d{2}):(\\d{2}):(\\d{2})/.test(value)\n && /(\\d{4})\\-(\\d{2})\\-(\\d{2})(\\s+|T)(\\d{2}):(\\d{2}):(\\d{2})/.test(filter)\n ) {\n\n if (tryEval(value.replace(/(\\d{4})\\-(\\d{2})\\-(\\d{2})(\\s+|T)(\\d{2}):(\\d{2}):(\\d{2})/, 'new Date(\"$&\")') + filter.replace(/(\\d{4})\\-(\\d{2})\\-(\\d{2})(\\s+|T)(\\d{2}):(\\d{2}):(\\d{2})/, 'new Date(\"$&\")'))) {\n\n ++matched;\n }\n\n } else if (tryEval(value + filter)) {\n\n ++matched;\n }\n\n } else {\n if (value == filter) {\n ++matched;\n }\n }\n\n } \n\n return {\n matched: matched\n }\n }\n\n // if one of the entry matches the given filter, tag the whole entry as matched\n var searchWithin = function(filter, f, _content, matched, i) {\n \n var collectionName = null\n , collection = null\n , arr = null\n , field = null;\n\n \n arr = f.split(/\\[\\*\\]/g);\n collectionName = arr[0].replace(/\\[\\*\\]/, '');// only take the first collection\n collection = _content[ collectionName ];\n \n \n field = arr[1];\n if (/^\\./.test(field) )\n field = field.substr(1);\n\n var subMatched = 0;\n if (collection) {\n \n for (var c = 0, cLen = collection.length; c < cLen; ++c) {\n // cases with _filter.prop\n if (/\\./.test(field)) {\n\n searchResult = searchThroughProp(filter, field, collection[c], subMatched);\n subMatched = searchResult.matched;\n\n } else { // normal case\n\n searchResult = search(filter, field, collection[c], subMatched, searchOptionRules);\n subMatched = searchResult.matched;\n }\n\n if (subMatched > 0) break;\n }\n }\n \n return {\n matched: (matched + subMatched)\n }\n }\n\n \n for (var o in tmpContent) {\n\n if (!tmpContent[o]) {\n tmpContent[o] = {}\n }\n \n if (!/undefined|function/.test( typeof(tmpContent[o]))) {\n \n for (let l = 0, lLen = filters.count(); l<lLen; ++l) {\n filter = filters[l];\n condition = filter.count();\n // for each condition \n matched = 0;\n \n for (var f in filter) {\n if ( typeof(filter[f]) == 'undefined' ) throw new Error('filter `'+f+'` cannot be left undefined');\n\n localeLowerCase = ( filter[f] !== null && !/(boolean|number)/.test(typeof(filter[f])) ) ? filter[f].toLocaleLowerCase() : filter[f];\n \n // cases with tmpContent.prop\n if (/\\./.test(f)) {\n //JSON.stringify(tmpContent[o]).match(/(\"gross\":\\w+)/)[1].split(/:/)[1]\n\n // detect if array|collection case\n if (/\\[\\*\\]/.test(f)) {\n\n searchResult = searchWithin(filter[f], f, tmpContent[o], matched, 0);\n matched = searchResult.matched;\n\n } else {\n\n searchResult = searchThroughProp(filter[f], f, tmpContent[o], matched);\n matched = searchResult.matched;\n }\n\n } else { // normal case\n \n searchResult = search(filter[f], f, tmpContent[o][f], matched, searchOptionRules); \n matched = searchResult.matched;\n } \n }\n\n if (matched == condition ) { // all conditions must be fulfilled to match\n // `this` {Array} is the result of the previous search or the current content\n // TODO - Add a switch \n if (\n withOrClause \n && notInSearchModeEnabled\n && searchIndex.indexOf(tmpContent[o]._uuid) < 0 \n || notInSearchModeEnabled\n || !withOrClause\n ) {\n //console.debug('searchIndex ', searchIndex);\n if (!withOrClause || withOrClause && result.indexOf(tmpContent[o]._uuid) < 0 || notInSearchModeEnabled) {\n result[i] = tmpContent[o];\n ++i;\n }\n } else if (\n withOrClause\n && !notInSearchModeEnabled\n ) {\n if (result.indexOf(tmpContent[o]._uuid) < 0) {\n result[i] = tmpContent[o];\n ++i;\n } \n }\n }\n\n }\n \n }\n }\n } else {\n result = content\n }\n\n // reset localSearchOptions for nest calls\n localSearchOptions = null;\n \n // TODO - remove this\n //if (withOrClause) {\n // merging with previous result\n //console.debug('withOrClause: supposed to merge ? \\nnotInSearchModeEnabled: '+notInSearchModeEnabled+'\\nResult: ' +result)//+'\\nThis: '+ this.toRaw();\n // if (!notInSearchModeEnabled) {\n // result = merge(this, result);\n // }\n // TODO - remove this part\n // Removed this on 2021-01-21 because it was causing duplicate content\n //result = merge(this, result, true) \n //}\n\n // chaining\n //result._options = instance._options;\n //result.setSearchOption = instance.setSearchOption;\n \n result.insert = instance.insert;\n result.notIn = instance.notIn;\n result.find = this.find;\n result.update = instance.update;\n result.replace = instance.replace;\n result.or = instance.or;\n result.findOne = instance.findOne;\n result.limit = instance.limit;\n result.orderBy = instance.orderBy;\n result.delete = instance.delete;\n result.toRaw = instance.toRaw;\n result.filter = instance.filter;\n\n return result\n }\n \n /** \n * findOne\n * \n * E.g.: \n * - new Collection(projects).findOne({name: 'My Project'})\n * - new Collection(projects)\n * .setSearchOption({name: { isCaseSensitive: false }})\n * .findOne({name: 'my project'})\n * \n * \n * Available options :\n * isCaseSensitive: [true|false] - set to true by default\n * \n * @param {object} filter\n * \n * @returns {object} result\n * \n */\n instance['findOne'] = function() {\n var key = null // comparison key\n , result = null\n , filters = null\n //, uuidSearchModeEnabled = true\n ;\n\n if ( typeof(arguments[arguments.length-1]) == 'string' ) {\n key = arguments[arguments.length - 1];\n delete arguments[arguments.length - 1];\n --arguments.length;\n }\n \n // if ( typeof(arguments[arguments.length-1]) == 'boolean' ) {\n // uuidSearchModeEnabled = arguments[arguments.length - 1]\n // delete arguments[arguments.length - 1];\n // --arguments.length;\n // }\n \n if (arguments.length > 0) {\n filters = arguments;\n }\n \n\n if ( typeof(filters) == 'undefined' || !filters || typeof(filters) != 'object' ) {\n throw new Error('[ Collection ][ findOne ] `filters` argument must be defined: Array or Filter Object(s) expected');\n }\n\n // If an operation (find, insert ...) has been executed, get the previous result; if not, get the whole collection\n //var currentResult = JSON.clone( (Array.isArray(this)) ? this : content );\n var currentResult = null;\n var foundResults = null;\n if ( Array.isArray(arguments[0]) ) {\n foundResults = arguments[0];\n } else {\n foundResults = instance.find.apply(this, arguments) || [];\n }\n \n if (foundResults.length > 0) {\n currentResult = foundResults.limit(1).toRaw()[0]; \n }\n\n result = currentResult;\n return result\n }\n\n\n instance['or'] = function () {\n arguments[arguments.length] = true;\n ++arguments.length;\n\n return instance.find.apply(this, arguments);\n }\n\n instance['limit'] = function(resultLimit) {\n if ( typeof(resultLimit) == 'undefined' || typeof(resultLimit) != 'number' ) {\n throw new Error('[Collection::result->limit(resultLimit)] : `resultLimit` parametter must by a `number`')\n }\n\n var result = Array.isArray(this) ? this : JSON.clone(content);\n\n //resultLimit\n result = result.splice(0, resultLimit);\n\n // chaining\n result.insert = instance.insert;\n result.update = instance.update;\n result.replace = instance.replace;\n result.notIn = instance.notIn;\n result.findOne = instance.findOne;\n result.orderBy = instance.orderBy;\n result.max = instance.max;\n result.delete = instance.delete;\n result.toRaw = instance.toRaw;\n result.filter = instance.filter;\n\n return result\n }\n \n /** \n * notIn\n * Works like a filter to match results by `excluding` through given `filters` !!\n * \n * filter can be like \n * { car: 'toyota' }\n * { car: 'toyota', color: 'red' }\n * \n * You can pass more than one filter\n * { car: 'toyota', color: 'red' }, { car: 'porche' }\n * \n * .notIn(filter) // AND syntax\n * .notIn(filter1, filter2, filter3) // OR syntax\n * .notIn(filter, 'id') where `id` is the uuid used for the DIFF - `_uuid\n * .noIn(collectionObj, 'id')\n * \n * By default, Collection use its own internal `_uuid` to search and compare.\n * This mode is called `uuidSearchModeEnabled`, and it is by default set to `true`.\n * If you want to disable this mode in order to MATCH/DIFF by forcing check on every single filter\n * of the resultset :\n * .notIn(filter, false) where false must be a real boolean\n * \n * \n * \n * @param {object|array} filters|arrayToFilter - works like find filterss\n * @param {string} [key] - unique id for comparison; faster when provided\n */\n instance['notIn'] = function(){\n\n var arrayToFilter = null // [] those that we don't want in the result\n , key = null // string comparison key\n , result = null\n , filters = null\n , uuidSearchModeEnabled = true\n ;\n\n if ( typeof(arguments[arguments.length-1]) == 'string' ) {\n key = arguments[arguments.length - 1];\n delete arguments[arguments.length - 1];\n --arguments.length;\n }\n \n if ( typeof(arguments[arguments.length-1]) == 'boolean' ) {\n uuidSearchModeEnabled = arguments[arguments.length - 1]\n delete arguments[arguments.length - 1];\n --arguments.length;\n }\n \n if (arguments.length > 0) {\n filters = arguments;\n }\n \n\n if ( typeof(filters) == 'undefined' || !filters || typeof(filters) != 'object' ) {\n throw new Error('[ Collection ][ notIn ] `filters` argument must be defined: Array or Filter Object(s) expected');\n }\n\n // If an operation (find, insert ...) has been executed, get the previous result; if not, get the whole collection\n var currentResult = JSON.clone( (Array.isArray(this)) ? this : content );\n \n var foundResults = null;\n if ( Array.isArray(arguments[0]) ) {\n foundResults = arguments[0];\n } else {\n notInSearchModeEnabled = true;\n foundResults = instance.find.apply(this, arguments) || [];\n notInSearchModeEnabled = false;\n }\n \n \n if (foundResults.length > 0) {\n \n // check key\n if ( \n uuidSearchModeEnabled\n && key \n && typeof(foundResults[0]) == 'undefined' \n && typeof(foundResults[0][key]) == 'undefined' \n ) {\n throw new Error('[ Collection ][ notIn ] `key` not valid');\n } else if ( uuidSearchModeEnabled && !key && typeof(foundResults[0]['_uuid']) != 'undefined' ) {\n key = '_uuid'\n } else if ( typeof(foundResults[0]['id']) != 'undefined' ) {\n key = 'id';\n }\n \n if ( !key || typeof(foundResults[0][key]) == 'undefined' ) {\n throw new Error('No comparison key defined !')\n } \n\n // fast search with key\n var r = 0\n , rLen = foundResults.length\n , c = 0\n , cLen = currentResult.length\n , f = 0\n , fLen = filters.count()\n , keyLen = null\n , matched = 0\n , fullFiltersMatched = 0\n ;\n if ( uuidSearchModeEnabled && typeof(currentResult[c]) != 'undefined' && currentResult[c].hasOwnProperty(key) ) {\n // for every single result found \n for (; r < rLen; ++r) {\n \n if (!currentResult.length) break;\n \n c = 0; cLen = currentResult.length;\n for (; c < cLen; ++c) {\n if ( typeof(currentResult[c]) == 'undefined' || typeof(foundResults[r]) == 'undefined' ) {\n continue\n }\n // when matched, we want to remove those not in current result \n if (currentResult[c][key] === foundResults[r][key]) {\n currentResult.splice(c,1);\n break;\n }\n }\n }\n } else if ( typeof(currentResult[c]) == 'undefined' ) { //empty source case\n // means that since we don't have a source to compare, current === found\n currentResult = JSON.clone(foundResults);\n \n } else { // search based on provided filters\n // for every single result found \n for (; r < rLen; ++r) {\n if (!currentResult.length) break; \n \n //onRemoved:\n c = 0; cLen = currentResult.length;\n for (; c < cLen; ++c) { // current results \n \n if ( typeof (currentResult[c]) != 'undefined' ) {\n \n // for each filter\n fullFiltersMatched = 0; \n f = 0; \n for (; f < fLen; ++f ) {\n if ( typeof(filters[f]) == 'undefined' ) throw new Error('filter `'+f+'` cannot be left undefined');\n \n keyLen = filters[f].count();\n matched = 0;\n for (key in filters[f]) {\n if ( currentResult[c].hasOwnProperty(key) && currentResult[c][key] === foundResults[r][key] ) {\n ++matched;\n } \n } \n if (matched == keyLen) {\n ++fullFiltersMatched\n } \n }\n \n if (fullFiltersMatched) {\n currentResult.splice(c,1);\n //break onRemoved;\n break;\n }\n \n }\n }\n }\n } \n \n } \n\n result = currentResult;\n result.notIn = instance.notIn;\n result.limit = instance.limit;\n result.find = instance.find;\n result.findOne = instance.findOne;\n result.insert = instance.insert;\n result.replace = instance.replace;\n result.update = instance.update;\n result.orderBy = instance.orderBy;\n result.max = instance.max;\n result.delete = instance.delete;\n result.toRaw = instance.toRaw;\n result.filter = instance.filter;\n\n return result\n }\n\n instance['insert'] = function (set) {\n\n var result = null;\n if ( typeof(set) !== 'object' ) {\n throw new Error('filter must be an object');\n } else {\n\n var tmpContent = Array.isArray(this) ? this : content;\n\n // Indexing;\n set._uuid = uuid.v4();\n tmpContent.push(set);\n\n result = tmpContent;\n }\n\n // chaining\n result.limit = instance.limit;\n result.find = instance.find;\n result.findOne = instance.findOne;\n result.update = instance.update;\n result.replace = instance.replace;\n result.orderBy = instance.orderBy;\n result.max = instance.max;\n result.notIn = instance.notIn;\n result.delete = instance.delete;\n result.toRaw = instance.toRaw;\n result.filter = instance.filter;\n\n return result\n }\n\n /**\n * update\n * \n * @param {object} filter\n * @param {object} set\n * \n * @returns {objet} instance\n */ \n instance['update'] = function() {\n var key = '_uuid' // comparison key is _uuid by default\n , result = null\n , filters = null\n , set = null\n //, uuidSearchModeEnabled = true\n ;\n\n // comparison key : _uuid by default, but can be set to id \n if ( typeof(arguments[arguments.length-1]) == 'string' ) {\n key = arguments[arguments.length - 1];\n delete arguments[arguments.length - 1];\n --arguments.length;\n } \n \n if ( typeof(arguments[arguments.length-1]) == 'object' ) {\n set = arguments[arguments.length - 1];\n delete arguments[arguments.length - 1];\n --arguments.length\n }\n \n // if ( typeof(arguments[arguments.length-1]) == 'boolean' ) {\n // uuidSearchModeEnabled = arguments[arguments.length - 1]\n // delete arguments[arguments.length - 1];\n // --arguments.length;\n // }\n \n if (arguments.length > 0) {\n filters = arguments;\n }\n \n\n if ( typeof(filters) == 'undefined' || !filters || typeof(filters) != 'object' ) {\n throw new Error('[ Collection ][ update ] `filters` argument must be defined: Array or Filter Object(s) expected');\n }\n \n if ( typeof(set) == 'undefined' || !set || typeof(set) != 'object' ) {\n throw new Error('[ Collection ][ update ] `set` argument must be defined: Object expected');\n }\n\n // If an operation (find, insert ...) has been executed, get the previous result; if not, get the whole collection\n var foundResults = null;\n if ( Array.isArray(arguments[0]) ) {\n foundResults = arguments[0];\n } else {\n foundResults = instance.find.apply(this, arguments) || [];\n }\n \n result = Array.isArray(this) ? this : JSON.clone(content);\n if (foundResults.length > 0 ) { \n var arr = foundResults.toRaw();\n for (var a = 0, aLen = arr.length; a < aLen; ++a) { \n arr[a] = merge( JSON.clone(set), arr[a]);\n for (var r = 0, rLen = result.length; r < rLen; ++r) {\n if ( typeof(result[r][key]) == 'undefined' && key == '_uuid' && typeof(result[r]['id']) != 'undefined' ) {\n key = 'id';\n }\n \n if ( result[r][key] == arr[a][key] ) {\n result[r] = arr[a];\n break;\n }\n }\n } \n }\n\n // chaining\n result.limit = instance.limit;\n result.find = instance.find;\n result.findOne = instance.findOne;\n result.insert = instance.insert;\n result.update = instance.update;\n result.replace = instance.replace;\n result.orderBy = instance.orderBy;\n result.max = instance.max;\n result.notIn = instance.notIn;\n result.delete = instance.delete;\n result.toRaw = instance.toRaw;\n result.filter = instance.filter;\n\n return result\n }\n \n \n instance['replace'] = function() {\n var key = '_uuid' // comparison key\n , result = null\n , filters = null\n , set = null\n //, uuidSearchModeEnabled = true\n ;\n\n \n if ( typeof(arguments[arguments.length-1]) == 'string' ) {\n key = arguments[arguments.length - 1];\n delete arguments[arguments.length - 1];\n --arguments.length;\n } \n \n if ( typeof(arguments[arguments.length-1]) == 'object' ) {\n set = arguments[arguments.length - 1];\n delete arguments[arguments.length - 1];\n --arguments.length;\n }\n \n // if ( typeof(arguments[arguments.length-1]) == 'boolean' ) {\n // uuidSearchModeEnabled = arguments[arguments.length - 1]\n // delete arguments[arguments.length - 1];\n // --arguments.length;\n // }\n \n if (arguments.length > 0) {\n filters = arguments;\n }\n \n\n if ( typeof(filters) == 'undefined' || !filters || typeof(filters) != 'object' ) {\n throw new Error('[ Collection ][ update ] `filters` argument must be defined: Array or Filter Object(s) expected');\n }\n \n if ( typeof(set) == 'undefined' || !set || typeof(set) != 'object' ) {\n throw new Error('[ Collection ][ update ] `set` argument must be defined: Object expected');\n }\n\n // If an operation (find, insert ...) has been executed, get the previous result; if not, get the whole collection\n //var currentResult = JSON.clone( (Array.isArray(this)) ? this : content );\n var currentResult = null;\n var foundResults = null;\n if ( Array.isArray(arguments[0]) ) {\n foundResults = arguments[0];\n } else {\n foundResults = instance.find.apply(this, arguments) || [];\n }\n \n result = Array.isArray(this) ? this : JSON.clone(content);\n if (foundResults.length > 0 ) { \n var arr = foundResults.toRaw();\n for (var a = 0, aLen = arr.length; a < aLen; ++a) { \n arr[a] = JSON.clone(set);\n for (var r = 0, rLen = result.length; r < rLen; ++r) {\n if ( typeof(result[r][key]) == 'undefined' && key == '_uuid' && typeof(result[r]['id']) != 'undefined' ) {\n key = 'id';\n } else if (typeof(result[r][key]) == 'undefined' && key == '_uuid') {\n throw new Error('No comparison key defined !')\n } \n \n if ( result[r][key] == arr[a][key] ) {\n result[r] = arr[a];\n break;\n }\n }\n } \n }\n\n // chaining\n result.limit = instance.limit;\n result.find = instance.find;\n result.findOne = instance.findOne;\n result.insert = instance.insert;\n result.update = instance.update;\n result.replace = instance.replace;\n result.orderBy = instance.orderBy;\n result.max = instance.max;\n result.notIn = instance.notIn;\n result.delete = instance.delete;\n result.toRaw = instance.toRaw;\n result.filter = instance.filter;\n\n return result\n }\n \n /**\n * .delete({ key: 2 })\n * .delete({ name: 'Jordan' }, ''id) where id will be use as the `uuid` to compare records\n * \n * AND syntax\n * .delete({ car: 'toyota', color: 'red' })\n * \n * OR syntax\n * .delete({ car: 'toyota', color: red }, { car: 'ford' } ) // will delete all `toyota red cars` & all `ford cars`\n * \n * N.B.: will not affect current result - just returning the DIFF\n * If you\n * @param {object} filter - samme as `.find(filter)`\n * @param {string|boolean} [ uuid | disabled ] - by default, Collection is using its internal _uuid\n * If you want to delete without key comparison, disable `uuid` search mode\n * .delete({ name: 'Jordan' }, false)\n * \n * @returns {array} result\n */\n instance['delete'] = function() {\n\n var result = instance.notIn.apply(this, arguments);\n\n result.limit = instance.limit;\n result.find = instance.find;\n result.findOne = instance.findOne;\n result.insert = instance.insert;\n result.update = instance.update;\n result.replace = instance.replace;\n result.orderBy = instance.orderBy;\n result.max = instance.max;\n result.notIn = instance.notIn;\n result.toRaw = instance.toRaw;\n result.filter = instance.filter;\n result.delete = this.delete;\n\n return result\n }\n\n\n var sortKeywords = [ 'asc', 'desc' ];\n /**\n * sort\n *\n * @param {object|array} filter\n * */\n instance['orderBy'] = function () {\n \n if ( typeof(arguments) == 'undefined' || arguments.length < 1)\n throw new Error('[ Collection->orderBy(filter) ] where `filter` must not be empty or null' );\n \n var filter = null;\n if ( arguments.length == 1 ) {\n filter = arguments[0];\n } else {\n // converting arguments into array\n filter = new Array(arguments.length);\n for (var f = 0, fLen = filter.length; f < fLen; ++f) {\n filter[f] = arguments[f]\n }\n }\n\n var variableContent = (Array.isArray(this)) ? this : JSON.clone(content);\n return sortResult(filter, variableContent.toRaw())\n }\n \n /**\n * max\n * E.g: \n * myCollection.max({ order: 'not null'})\n * => 5\n * myCollection.max({ createAt: 'not null'})\n * => '2021-12-31T23:59:59'\n * myCollection.max({ firstName: 'not null'})\n * => 'Zora'\n * \n * @param {object|array} filter\n * \n * @returns {number|date|string}\n * */\n instance['max'] = function () {\n if ( typeof(arguments) == 'undefined' || arguments.length < 1)\n throw new Error('[ Collection->max(filter) ] where `filter` must not be empty or null' );\n \n var filter = null;\n if ( \n arguments.length > 1\n || Array.isArray(arguments[0])\n || typeof(arguments[0]) == 'object' && arguments[0].count() > 1\n ) {\n throw new Error('[ Collection->max(filter) ] only accept one filter length, and fileter count must be equal to 1' );\n }\n filter = arguments[0];\n try {\n var key = Object.keys(filter)[0];\n var subFilter = {};\n subFilter[key] = 'desc';\n return instance['find'](filter).orderBy(subFilter).limit(1)[0][key];\n } catch (err) {\n throw err\n }\n }\n\n /**\n * sortResult\n * ref.:\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#Browser_compatibility\n *\n * e.g.:\n * .orderBy({ name: 'asc' })\n *\n * // overriding filters -> last filter is always right\n * .orderBy([ { updatedAt : 'desc'}, { name: 'asc' } ])\n * \n * // sorting boolean \n * .orderBy({ isActive: 'desc'}) => will display all active(TRUE) first\n * NB.: Boolean are 0 (FALSE) or 1 (TRUE)\n * \n * // combining filters -> the first one is always right\n * .orderBy({ updatedAt : 'desc'}, { name: 'asc' })\n *\n * @param {object|array} filter\n * */\n var sortResult = function (filter, content) {\n if ( typeof(filter) != 'object') {\n throw new Error('`filter` parametter must be an object or an array')\n }\n\n var condition = filter.count()\n , sortOp = {}\n , multiSortOp = null\n , sortRecursive = null\n , key = null\n , prop = null\n , result = []\n ;\n\n if (condition == 0) return null;\n\n\n // asc\n sortOp['asc'] = function (prop, content) {\n\n var mapped = content.map(function(obj, i) {\n var _m = {};\n _m.index = i;\n _m[prop] = obj[prop];\n return _m;\n });\n \n mapped.sort(function onAscSort(a, b) { \n \n \n var _compare = function(a, b) {\n // handle booleans\n if ( /^(true|false)$/i.test(a) ) {\n a = ( /true/i.test(a) ) ? 1 : 0;\n }\n \n if ( /^(true|false)$/i.test(b) ) {\n b = ( /true/i.test(b) ) ? 1 : 0;\n }\n \n \n if ( typeof(a) == 'string' && a != '' || typeof(b) == 'string' ) {\n \n if ( typeof(a) == 'number' ) {\n a = ''+a; // cast to string\n } \n if ( typeof(b) == 'number' ) {\n b = ''+b; // cast to string\n } \n \n return a.localeCompare(b, undefined, {sensitivity: 'case', caseFirst: 'upper'})\n }\n \n if (a > b) {\n return 1;\n }\n if (a < b) {\n return -1;\n }\n // a must be equal to b\n return 0; \n }\n \n \n if ( typeof(a) == 'object' ) {\n return _compare(a[prop], b[prop])\n }\n \n return _compare(a, b)\n \n });\n \n return mapped.map(function(m, index, result){\n return content[m.index];\n });\n }\n\n // desc\n sortOp['desc'] = function (prop, content) {\n return sortOp['asc'](prop, content).reverse()\n }\n\n multiSortOp = function(content, filter) {\n \n var props = [], keys = [];\n \n if ( Array.isArray(filter) ) {\n for (var f = 0, fLen = filter.length; f < fLen; ++f) {\n props[f] = Object.keys(filter[f])[0];\n keys[f] = filter[f][ props[f]] ; \n }\n } else {\n var f = 0;\n for (var flt in filter) {\n props[f] = flt;\n keys[f] = filter[flt] ; \n ++f;\n }\n }\n \n \n\n sortRecursive = function(a, b, columns, order_by, index) {\n\n var direction = order_by[index] == 'desc' ? 1 : 0;\n\n var res = null, x = null, y = null;\n\n if ( typeof(a[columns[index]]) == 'string' && a[columns[index]] != '' ) {\n\n res = a[columns[index]].localeCompare(b[columns[index]]);\n\n if ( direction == 0 && res != 0 ) {\n return res < 0 ? -1 : 1\n } else if (res != 0) {\n return res < 0 ? 1 : -1\n }\n \n // a must be equal to b\n return columns.length - 1 > index ? sortRecursive(a, b, columns, order_by, index + 1) : 0;\n\n } else if (typeof (a[columns[index]]) == 'number' || typeof(b[columns[index]]) == 'number' ) {\n\n res = (''+ a[columns[index]]).localeCompare((''+ b[columns[index]]), undefined, { numeric: true });\n\n if (direction == 0 && res != 0) {\n return res < 0 ? -1 : 1\n } else if (res != 0) {\n return res < 0 ? 1 : -1\n }\n\n // a must be equal to b\n return columns.length - 1 > index ? sortRecursive(a, b, columns, order_by, index + 1) : 0;\n\n } else if ( typeof(a[columns[index]]) == 'boolean' || typeof (b[columns[index]]) == 'boolean' ) {\n\n if ( typeof(a[columns[index]]) == 'boolean' ) {\n x = (a[columns[index]]) ? 1 : 0;\n }\n\n if ( typeof(b[columns[index]]) == 'boolean' ) {\n y = (b[columns[index]]) ? 1 : 0;\n }\n\n if (x > y) {\n return direction == 0 ? 1 : -1;\n }\n\n if (x < y) {\n return direction == 0 ? -1: 1;\n }\n\n // a must be equal to b\n return columns.length - 1 > index ? sortRecursive(a, b, columns, order_by, index + 1) : 0;\n\n } else {\n\n if (a[columns[index]] > b[columns[index]]) {\n return direction == 0 ? 1 : -1;\n }\n\n if (a[columns[index]] < b[columns[index]]) {\n return direction == 0 ? -1 : 1;\n }\n // a must be equal to b\n return columns.length - 1 > index ? sortRecursive(a, b, columns, order_by, index + 1) : 0;\n }\n }\n\n return content.sort(function onMultiSort(a, b) {\n return sortRecursive(a, b, props, keys, 0);\n });\n // return mapped.map(function(m, index, result){\n // return content[m.index];\n // });\n }\n\n if ( Array.isArray(filter) || filter.count() > 1 ) {\n \n result = multiSortOp(content, filter);\n \n } else {\n \n prop = Object.keys(filter)[0];\n key = filter[prop];\n\n result = sortOp[key](prop, content);\n }\n\n\n\n // chaining\n result.find = instance.find;\n result.findOne = instance.findOne;\n result.limit = instance.limit;\n result.notIn = instance.notIn;\n result.insert = instance.insert;\n result.update = instance.update;\n result.replace = instance.replace;\n result.delete = instance.delete;\n result.orderBy = instance.orderBy;\n result.max = instance.max;\n result.toRaw = instance.toRaw;\n result.filter = instance.filter;\n \n return result\n };\n\n /**\n * toRaw\n * Transform result into a clean format (without _uuid)\n *\n * @returns {array} result\n * */\n instance['toRaw'] = function() {\n\n var result = ( Array.isArray(this) ) ? this : content;\n // cleanup\n for (var i = 0, len = result.length; i < len; ++i) {\n if (result[i]._uuid)\n delete result[i]._uuid;\n }\n\n return JSON.clone(result);\n }\n \n /**\n * filter\n * Reduce record propName\n * @param {string|array} filter\n * e.g: 'id'\n * e.g: ['id', 'name']\n *\n * @returns {array} rawFilteredResult\n * */\n instance['filter'] = function(filter) {\n \n if ( typeof(filter) == 'undefined' ) {\n throw new Error('`filter` parametter must be a string or an array.');\n }\n var result = ( Array.isArray(this) ) ? this : content;\n if ( !result.length ) {\n return []\n }\n var i = 0, len = result.length;\n var rawFilteredResult = [], fCount = 0;\n \n if ( Array.isArray(filter) ) {\n var f = null, fLen = filter.length, wrote = null;\n for (; i < len; ++i) {\n wrote = false;\n f = 0;\n for (; f < fLen; ++f) {\n if ( typeof(result[i][ filter[f] ]) != 'undefined' ) {\n if ( typeof(rawFilteredResult[fCount]) == 'undefined' ) {\n rawFilteredResult[fCount] = {}\n }\n rawFilteredResult[fCount][ filter[f] ] = result[i][ filter[f] ];\n wrote = true;\n }\n }\n if (wrote)\n ++fCount;\n }\n } else {\n for (; i < len; ++i) {\n if ( typeof(result[i][filter]) != 'undefined' ) {\n if ( typeof(rawFilteredResult[fCount]) == 'undefined' ) {\n rawFilteredResult[fCount] = {}\n }\n rawFilteredResult[fCount][filter] = result[i][filter];\n ++fCount;\n }\n }\n } \n\n return JSON.clone(rawFilteredResult);\n }\n \n \n return instance;\n};\n\nif ( ( typeof(module) !== 'undefined' ) && module.exports ) {\n // Publish as node.js module\n module.exports = Collection\n} else if ( typeof(define) === 'function' && define.amd) {\n // Publish as AMD module\n define('utils/collection',[],function() { return Collection })\n};\n",
|
|
40
|
-
"/**\n * FormValidatorUtil\n *\n * Dependencies:\n * - utils/helpers\n * - utils/helpers/dateFormat\n * - utils/merge\n * - utils/routing (for API calls)\n *\n * @param {object} data\n * @param {object} [ $fields ] - isGFFCtx only\n * @param {object} [ xhrOptions ] - isGFFCtx only\n * @param {object} [ fieldsSet ] - isGFFCtx only; required for when ginaFormLiveCheckEnabled\n * */\nfunction FormValidatorUtil(data, $fields, xhrOptions, fieldsSet) {\n\n var isGFFCtx = ( ( typeof(module) !== 'undefined' ) && module.exports ) ? false : true;\n\n // if (isGFFCtx && !$fields )\n // throw new Error('No `Validator` instance found.\\nTry:\\nvar FormValidator = require(\"gina/validator\"):\\nvar formValidator = new FormValidator(...);')\n \n var merge = (isGFFCtx) ? require('utils/merge') : require('../../../../../lib/merge');\n var helpers = (isGFFCtx) ? {} : require('../../../../../helpers');\n var dateFormat = (isGFFCtx) ? require('helpers/dateFormat') : helpers.dateFormat;\n var routing = (isGFFCtx) ? require('utils/routing') : require('../../../../../lib/routing');\n \n var hasUserValidators = function() {\n \n var _hasUserValidators = false, formsContext = null;\n // backend validation check\n if (!isGFFCtx) {\n // TODO - retrieve bakcend forms context\n formsContext = getContext('gina').forms || null;\n } else if (isGFFCtx && typeof(gina.forms) != 'undefined') {\n formsContext = gina.forms\n }\n if ( formsContext && typeof(formsContext.validators) != 'undefined' ) {\n _hasUserValidators = true\n }\n return _hasUserValidators;\n } \n /**@js_externs local*/\n var local = {\n 'errors': {},\n 'keys': {\n '%l': 'label', // %l => label: needs `data-gina-form-field-label` attribute (frontend only)\n '%n': 'name', // %n => field name\n '%s': 'size' // %s => length\n },\n 'errorLabels': {},\n 'data': {}, // output to send\n 'excluded': []\n };\n\n local.errorLabels = {\n 'is': 'Condition not satisfied',\n 'isEmail': 'A valid email is required',\n 'isRequired': 'Cannot be left empty',\n 'isBoolean': 'Must be a valid boolean',\n 'isNumber': 'Must be a number: allowed values are integers or floats',\n 'isNumberLength': 'Must contain %s characters',\n 'isNumberMinLength': 'Should be at least %s characters',\n 'isNumberMaxLength': 'Should not be more than %s characters',\n 'isInteger': 'Must be an integer',\n 'isIntegerLength': 'Must have %s characters',\n 'isIntegerMinLength': 'Should be at least %s characters',\n 'isIntegerMaxLength': 'Should not be more than %s characters',\n 'toInteger': 'Could not be converted to integer',\n 'isFloat': 'Must be a proper float',\n 'isFloatException': 'Float exception found: %n',\n 'toFloat': 'Could not be converted to float',\n 'toFloatNAN': 'Value must be a valid number',\n 'isDate': 'Must be a valid Date',\n 'isString': 'Must be a string',\n 'isStringLength': 'Must have %s characters',\n 'isStringMinLength': 'Should be at least %s characters',\n 'isStringMaxLength': 'Should not be more than %s characters',\n 'isJsonWebToken': 'Must be a valid JSON Web Token',\n 'query': 'Must be a valid response',\n 'isApiError': 'Condition not satisfied'\n };\n var self = null;\n if (!data) {\n throw new Error('missing data param')\n } else {\n // cloning\n self = merge( JSON.clone(data), self );\n local.data = merge( JSON.clone(data), local.data);\n }\n \n var getElementByName = function($form, name) { // frontend only\n var $foundElement = null;\n for (let f in fieldsSet) {\n if (fieldsSet[f].name !== name) continue;\n \n $foundElement = new DOMParser()\n .parseFromString($form.innerHTML , 'text/html')\n .getElementById( fieldsSet[f].id );\n break;\n }\n if ($foundElement)\n return $foundElement;\n \n throw new Error('Field `'+ name +'` not found in fieldsSet');\n }\n \n /**\n * bufferToString - Convert Buffer to String\n * Will apply `Utf8Array` to `String`\n * @param {array} arrayBuffer \n */\n var bufferToString = function(arrayBuffer) { \n var out = null\n , i = null\n , len = null\n , c = null\n ;\n var char2 = null, char3 = null;\n\n out = '';\n len = arrayBuffer.length;\n i = 0;\n while(i < len) {\n c = arrayBuffer[i++];\n switch (c >> 4) { \n case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:\n // 0xxxxxxx\n out += String.fromCharCode(c);\n break;\n case 12: case 13:\n // 110x xxxx 10xx xxxx\n char2 = arrayBuffer[i++];\n out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));\n break;\n case 14:\n // 1110 xxxx 10xx xxxx 10xx xxxx\n char2 = arrayBuffer[i++];\n char3 = arrayBuffer[i++];\n out += String.fromCharCode(((c & 0x0F) << 12) |\n ((char2 & 0x3F) << 6) |\n ((char3 & 0x3F) << 0));\n break;\n }\n }\n\n return out;\n };\n \n // TODO - One method for the front, and one for the server\n var queryFromFrontend = function(options, errorMessage) {\n var errors = self[this['name']]['errors'] || {}; \n var id = this.target.id || this.target.getAttribute('id');\n \n \n // stop if \n // - previous error detected \n if ( !self.isValid() ) { \n console.debug('stopping on errors ...');\n triggerEvent(gina, this.target, 'asyncCompleted.' + id, self[this['name']]);\n //return self[this.name];\n return;\n }\n \n var testedValue = this.target.dataset.ginaFormValidatorTestedValue;\n console.debug('[ '+ this['name'] +' ]', 'TESTED VALUE -> ' + this.value +' vs '+ testedValue);\n var _evt = 'asyncCompleted.' + id;\n var currentFormId = this.target.form.getAttribute('id');\n var cachedErrors = (\n typeof(gina.validator) != 'undefined'\n && typeof(gina.validator.$forms[currentFormId]) != 'undefined'\n && typeof(gina.validator.$forms[currentFormId].cachedErrors) != 'undefined'\n )\n ? gina.validator.$forms[currentFormId].cachedErrors \n : null;\n if ( !testedValue || typeof(testedValue) == 'undefined' || testedValue !== this.value ) {\n this.target.dataset.ginaFormValidatorTestedValue = this.value;\n // remove cachedErrors\n if ( \n cachedErrors \n && typeof(cachedErrors[this.name]) != 'undefined'\n && typeof(cachedErrors[this.name].query) != 'undefined'\n ) {\n delete cachedErrors[this.name].query;\n if ( \n typeof(gina.validator.$forms[currentFormId]) != 'undefined'\n &&\n typeof(gina.validator.$forms[currentFormId].errors) != 'undefined'\n ) {\n delete gina.validator.$forms[currentFormId].errors.query;\n }\n \n }\n } else if (testedValue === this.value) {\n // not resending to backend, but in case of cached errors, re display same error message\n var hasCachedErrors = false; \n if ( \n cachedErrors \n && typeof(cachedErrors[this.name]) != 'undefined'\n && typeof(cachedErrors[this.name].query) != 'undefined' \n && typeof(cachedErrors[this.name].query[this.value]) != 'undefined' \n ) {\n this.error = errorMessage = cachedErrors[this.name].query[this.value].slice(0);\n hasCachedErrors = true;\n }\n errors['query'] = replace( this.error || errorMessage || local.errorLabels['query'], this);\n \n if (hasCachedErrors) {\n this['errors'] = errors;\n this.valid = false;\n }\n // Do not remove this test \n if ( typeof( gina.events[_evt]) != 'undefined' ) {\n triggerEvent(gina, this.target, _evt, self[this['name']]);\n } \n \n return self[this.name];\n }\n //console.debug('Did not return !!!');\n \n var xhr = null, _this = this;\n // setting up AJAX\n if (window.XMLHttpRequest) { // Mozilla, Safari, ...\n xhr = new XMLHttpRequest();\n } else if (window.ActiveXObject) { // IE\n try {\n xhr = new ActiveXObject(\"Msxml2.XMLHTTP\");\n } catch (e) {\n try {\n xhr = new ActiveXObject(\"Microsoft.XMLHTTP\");\n }\n catch (e) {}\n }\n }\n \n // forcing to sync mode\n var queryOptions = { isSynchrone: false, headers: {} }; \n var queryData = options.data || null, strData = null;\n var isInlineValidation = (/^true$/i.test(this.target.form.dataset.ginaFormLiveCheckEnabled)) ? true : false; // TRUE if liveCheckEnabled\n \n // replace placeholders by field values\n strData = JSON.stringify(queryData);\n if ( /\\$/.test(strData) ) {\n var variables = strData.match(/\\$[-_\\[\\]a-z 0-9]+/g) || [];\n var value = null, key = null; \n for (let i = 0, len = variables.length; i < len; i++) {\n key = variables[i].replace(/\\$/g, '');\n re = new RegExp(\"\\\\\"+ variables[i].replace(/\\[|\\]/g, '\\\\$&'), \"g\");\n value = local.data[key] || null;\n if (!value && isInlineValidation) {\n // Retrieving live value instead of using fieldsSet.value\n value = getElementByName(this.target.form, key).value;\n }\n \n strData = strData.replace( re, value );\n }\n }\n // cleanup before sending\n queryData = strData.replace(/\\\\\"/g, ''); \n // TODO - support regexp for validIf\n var validIf = ( typeof(options.validIf) == 'undefined' ) ? true : options.validIf;\n \n queryOptions = merge(queryOptions, options, xhrOptions);\n delete queryOptions.data;\n delete queryOptions.validIf;\n \n var enctype = queryOptions.headers['Content-Type'];\n var result = null\n , $target = this.target\n //, id = $target.getAttribute('id')\n ;\n id = $target.getAttribute('id')\n \n // checking url\n if (!/^http/.test(queryOptions.url) && /\\@/.test(queryOptions.url) ) {\n try {\n var route = routing.getRoute(queryOptions.url);\n queryOptions.url = route.toUrl();\n } catch (routingError) {\n throw routingError;\n }\n }\n \n if ( queryOptions.withCredentials ) {\n if ('withCredentials' in xhr) {\n // XHR for Chrome/Firefox/Opera/Safari.\n if (queryOptions.isSynchrone) {\n xhr.open(queryOptions.method, queryOptions.url, queryOptions.isSynchrone)\n } else {\n xhr.open(queryOptions.method, queryOptions.url)\n }\n } else if ( typeof XDomainRequest != 'undefined' ) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n // if (queryOptions.isSynchrone) {\n // xhr.open(queryOptions.method, queryOptions.url, queryOptions.isSynchrone);\n // } else {\n xhr.open(queryOptions.method, queryOptions.url);\n // } \n } else {\n // CORS not supported.\n xhr = null;\n result = 'CORS not supported: the server is missing the header `\"Access-Control-Allow-Credentials\": true` ';\n //triggerEvent(gina, $target, 'error.' + id, result);\n throw new Error(result);\n }\n \n if ( typeof(queryOptions.responseType) != 'undefined' ) {\n /**\n * Note: We expect to remove support for synchronous use of XMLHTTPRequest() during page unloads in Chrome in version 88, \n * scheduled to ship in January 2021.\n * The XMLHttpRequest2 spec was recently changed to prohibit sending a synchronous request when XMLHttpRequest.responseType\n */\n xhr.responseType = queryOptions.responseType;\n } else {\n xhr.responseType = '';\n }\n\n xhr.withCredentials = true;\n } else {\n if (queryOptions.isSynchrone) {\n xhr.open(queryOptions.method, queryOptions.url, queryOptions.isSynchrone)\n } else {\n xhr.open(queryOptions.method, queryOptions.url)\n }\n }\n \n // setting up headers - all but Content-Type ; it will be set right before .send() is called\n for (var hearder in queryOptions.headers) {\n if (hearder == 'Content-Type' && typeof (enctype) != 'undefined' && enctype != null && enctype != '')\n continue;\n\n xhr.setRequestHeader(hearder, queryOptions.headers[hearder]);\n } \n if (typeof (enctype) != 'undefined' && enctype != null && enctype != '') {\n xhr.setRequestHeader('Content-Type', enctype);\n }\n \n if (xhr) {\n \n xhr.onload = function () { \n \n var onResult = function(result) {\n \n _this.value = local['data'][_this.name] = (_this.value) ? _this.value.toLowerCase() : _this.value;\n \n var isValid = result.isValid || false;\n if (validIf != isValid) {\n isValid = false; \n } else {\n isValid = true;\n }\n self[_this['name']].valid = isValid;\n var errors = self[_this['name']]['errors'] || {};\n \n var errorFields = ( typeof(result.error) != 'undefined' && typeof(result.fields) != 'undefined' ) ? result.fields : {};\n \n if (errorFields.count() > 0 && !isValid || !isValid) {\n \n if (!isValid) {\n var systemError = null;\n if ( typeof(errorFields[_this.name]) != 'undefined') {\n local.errorLabels['query'] = errorFields[_this.name]; \n } else if ( typeof(result.error) != 'undefined' && /^5/.test(result.status) ) {\n // system error\n //console.debug('found system error: ', result);\n systemError = result.error;\n } \n errors['query'] = replace(systemError || _this['error'] || options['error'] || local.errorLabels['query'], _this);\n console.debug('query error detected !! ', result);\n }\n \n if ( !errors['query'] && _this.value == '' ) {\n isValid = true;\n }\n }\n \n // if error tagged by a previous validation, remove it when isValid == true \n if ( isValid && typeof(errors['query']) != 'undefined' ) {\n delete errors['query'];\n }\n \n // To handle multiple errors from backend\n // for (var f in errorFields.length) {\n // if ( !errors['query'] && _this.value == '' ) {\n // isValid = true;\n // }\n \n // if (!isValid) {\n // errors['query'] = replace(_this['error'] || local.errorLabels['query'], _this)\n // }\n // // if error tagged by a previous validation, remove it when isValid == true \n // else if ( isValid && typeof(errors['query']) != 'undefined' ) {\n // delete errors['query'];\n // }\n // }\n \n _this.valid = isValid;\n var cachedErrors = gina.validator.$forms[_this.target.form.getAttribute('id')].cachedErrors || {};\n if ( errors.count() > 0 ) {\n \n _this['errors'] = errors;\n if ( typeof(self[_this['name']].errors) == 'undefined' ) {\n self[_this['name']].errors = {};\n }\n \n self[_this['name']].errors = merge(self[_this['name']].errors, errors);\n \n if ( typeof(errors.query) != 'undefined' && errors.query ) {\n \n if ( typeof(cachedErrors[_this.name]) == 'undefined' ) {\n cachedErrors[_this.name] = {}\n }\n if ( typeof(cachedErrors[_this.name].query) == 'undefined' ) {\n cachedErrors[_this.name].query = {}\n }\n \n cachedErrors[_this.name].query[_this.value] = errors.query.slice(0);\n }\n \n var errClass = _this.target.getAttribute('data-gina-form-errors');\n if ( !/query/.test(errClass) ) {\n if ( !errClass || errClass =='' ) {\n errClass = 'query' \n } else {\n errClass +=' query'\n }\n _this.target.setAttribute('data-gina-form-errors', errClass);\n }\n } else if ( \n typeof(cachedErrors[_this.name]) != 'undefined'\n && typeof(cachedErrors[_this.name].query) != 'undefined'\n && typeof(cachedErrors[_this.name].query[_this.value]) != 'undefined'\n ) {\n delete cachedErrors[_this.name].query[_this.value];\n }\n \n var id = _this.target.id || _this.target.getAttribute('id');\n console.debug('prematurely completed event `'+ 'asyncCompleted.' + id +'`');\n return triggerEvent(gina, _this.target, 'asyncCompleted.' + id, self[_this['name']]);\n }\n \n try {\n result = this.responseText;\n var contentType = this.getResponseHeader(\"Content-Type\");\n if ( /\\/json/.test( contentType ) ) {\n result = JSON.parse(this.responseText);\n \n if ( typeof(result.status) == 'undefined' )\n result.status = this.status;\n \n //triggerEvent(gina, $target, 'success.' + id, result); \n return onResult(result)\n } else {\n result = { 'status': xhr.status, 'message': '' };\n if ( /^(\\{|\\[)/.test( xhr.responseText ) ) {\n try {\n result = merge( result, JSON.parse(xhr.responseText) );\n } catch (err) {\n result = merge(result, err);\n }\n }\n return onResult(result);\n }\n } catch (err) {\n throw err;\n } \n }\n \n if (data) {\n xhr.send( queryData ); // stringyfied\n } else {\n xhr.send();\n } \n }\n }\n \n /**\n * queryFromBackend\n * \n * \n * @param {object} options \n * @param {object} request \n * @param {object} response \n * @param {callback} next\n * \n * \n */\n var queryFromBackend = async function(options, request, response, next) {\n var Config = require(_(GINA_FRAMEWORK_DIR +'/core/config.js', true));\n var config = new Config().getInstance();\n \n var opt = null\n //appConf.proxy.<bundle>;\n , rule = null\n , bundle = null\n , currentBundle = getContext('bundle')\n ;\n // trying to retrieve proxy conf\n if ( /\\@/.test(options.url) ) {\n var attr = options.url.split(/@/); \n rule = attr[0];\n bundle = attr[1];\n var proxyConf = getConfig( currentBundle, 'app' ).proxy;\n try {\n if (config.bundle !== bundle) { // ignore if same bundle\n // getting proxy conf when available\n opt = getConfig( currentBundle, 'app' ).proxy[bundle];\n } \n } catch (proxyError) {\n throw new Error('Could not retrieve `proxy` configuration for bundle `'+ bundle +'`. Please check your `/config/app.json`.\\n'+proxyError.stack);\n }\n \n attr = null;\n } else {\n // TODO - handle else; when it is an external domain/url\n throw new Error('external url/domain not handled at this moment, please contact us if you need support for it.')\n }\n var route = JSON.clone(routing.getRoute(options.url, options.data));\n var env = config.env;\n var conf = config[bundle][env]; \n if (!opt) { // setup opt by default if no proxy conf found\n if (config.bundle == bundle) {\n var credentials = getConfig( currentBundle, 'settings' ).server.credentials;\n options.ca = credentials.ca || null;\n options.hostname = conf.server.scheme +'://'+ conf.host;\n options.port = conf.port[conf.server.protocol][conf.server.scheme];\n options.protocol = conf.server.protocol;\n options.rejectUnauthorized = false;\n }\n opt = { \n \"ca\" : options.ca,\n \"hostname\" : options.hostname, \n \"port\" : options.port, \n \"path\" : options.path\n };\n \n if ( typeof(options.protocol) != 'undefined' ) {\n opt.protocol = options.protocol\n }\n if ( typeof(options.rejectUnauthorized) != 'undefined' ) {\n opt.rejectUnauthorized = options.rejectUnauthorized\n }\n }\n \n /**\n * BO routing configuration\n * Attention: this portion of code is from `router.js`\n * Any modification on this part must be reflected on `router.js`\n */\n // default param setting\n var params = {\n method : route.method,\n requirements : route.requirements,\n namespace : route.namespace || undefined,\n url : unescape(route.url), /// avoid %20\n rule : rule + '@' + bundle,\n param : JSON.clone(route.param),\n middleware : JSON.clone(route.middleware),\n bundle : route.bundle,\n isXMLRequest : request.isXMLRequest,\n isWithCredentials : request.isWithCredentials\n };\n \n var templateName = params.rule.replace('\\@'+ bundle, '') || '_common';\n var routeHasViews = ( typeof(conf.content.templates) != 'undefined' ) ? true : false;\n var controllerOptions = {\n // view namespace first\n template: (routeHasViews) ? conf.content.templates[templateName] || conf.content.templates._common : undefined,\n // namespace : params.param.namespace || namespace,\n //control : route.param.control,\n // controller : controllerFile,\n //controller: '<span class=\"gina-bundle-name\">' + bundle +'</span>/controllers/controller.js',\n //file: route.param.file, // matches rule name by default\n //bundle : bundle,//module\n // bundlePath : conf.bundlesPath + '/' + bundle,\n // rootPath : self.executionPath,\n // We don't want to keep original conf untouched\n conf : JSON.clone(conf),\n //instance: self.serverInstance,\n //template: (routeHasViews) ? conf.content.templates[templateName] : undefined,\n //isUsingTemplate: local.isUsingTemplate,\n cacheless: conf.cacheless //,\n //path: params.param.path || null, // user custom path : namespace should be ignored | left blank\n //assets: {}\n };\n \n controllerOptions = merge(controllerOptions, params); \n \n // BO - Template outside of namespace fix added on 2021-08-19\n // We want to keep original conf untouched\n controllerOptions.conf = JSON.clone(conf);\n controllerOptions.conf.content.routing[controllerOptions.rule].param = params.param;\n // inheriting from _common\n if (\n controllerOptions.template\n && typeof(controllerOptions.template.ginaLoader) == 'undefined'\n ) {\n controllerOptions.template.ginaLoader = controllerOptions.conf.content.templates._common.ginaLoader;\n } \n controllerOptions.conf.content.routing[controllerOptions.rule].param = params.param;\n delete controllerOptions.middleware;\n delete controllerOptions.param;\n delete controllerOptions.requirements;\n // EO - Template outside of namespace\n /**\n * EO routing configuration\n */\n \n var Controller = require(_(GINA_FRAMEWORK_DIR +'/core/controller/controller.js'), true);\n var controller = new Controller(controllerOptions);\n controller.name = route.param.control; \n //controller.serverInstance = serverInstance;\n controller.setOptions(request, response, next, controllerOptions);\n \n \n var data = ( typeof(options.data) == 'object' && options.data.count() > 0 )\n ? options.data\n : {}; \n // inherited data from current query asking for validation\n var urlParams = '';\n if ( /^get|delete|put$/i.test(options.method) ) {\n urlParams += '?';\n var i = 0;\n for (let p in data) {\n if (i > 0) {\n urlParams += '&';\n }\n let val = (typeof(data[p]) == 'object') ? encodeURIComponent(JSON.stringify(data[p])) : data[p];\n urlParams += p +'='+ val;\n i++;\n }\n }\n opt.method = options.method;\n //opt.path = route.url + urlParams;\n opt.path = route.url;\n \n var util = require('util');\n var promisify = util.promisify;\n var result = { isValid: false }, err = false;\n \n await promisify(controller.query)(opt, data)\n .then(function onResult(_result) {\n result = _result;\n })\n .catch(function onResultError(_err) {\n err = _err;\n });\n if (err) {\n //throw err;\n console.error(err);\n result.error = err;\n } \n return result;\n };\n \n /**\n * query\n */\n var query = null;\n if (isGFFCtx) {\n query = queryFromFrontend;\n } else {\n query = queryFromBackend;\n }\n\n\n /**\n * addField\n * Add field to the validation context\n * @param {string} el \n * @param {string|boolean|number|object} [value] \n */\n var addField = function(el, value) { \n var val = null, label = null;\n \n if ( typeof(self[el]) == 'undefined' && typeof(value) != 'undefined' ) {\n self[el] = val = value;\n }\n \n if ( typeof(self[el]) == 'object' ) {\n try {\n val = JSON.parse( JSON.stringify( self[el] ))\n } catch (err) {\n val = self[el]\n }\n } else {\n val = self[el]\n }\n\n label = '';\n if ( isGFFCtx && typeof($fields) != 'undefined' ) { // frontend only\n label = $fields[el].getAttribute('data-gina-form-field-label') || '';\n }\n\n // keys are stringyfied because of the compiler !!!\n self[el] = {\n 'target': (isGFFCtx && typeof($fields) != 'undefined') ? $fields[el] : null,\n 'name': el,\n 'value': val,\n 'valid': false,\n // is name by default, but you should use setLabe(name) to change it if you need to\n 'label': label,\n // check as field to exclude while sending datas to the model\n 'exclude': false\n };\n\n /**\n *\n * is(condition) -> validate if value matches `condition`\n *\n * When entered in a JSON rule, you must double the backslashes\n *\n * e.g.:\n * \"/\\\\D+/\" -> like [^0-9]\n * \"!/^\\\\\\\\s+/\" -> not starting by white space allow\n * \"/^[0-9]+$/\" -> only numbers\n * \"$field === $fieldOther\" -> will be evaluated\n *\n * @param {object|string} condition - RegExp object, or condition to eval, or eval result\n * @param {string} [errorMessage] - error message\n * @param {string} [errorStack] - error stack\n *\n * */\n self[el]['is'] = function(condition, errorMessage, errorStack) {\n var isValid = false;\n var alias = ( typeof(window) != 'undefined' && typeof(window._currentValidatorAlias) != 'undefined' ) ? window._currentValidatorAlias : 'is';\n if ( typeof(window) != 'undefined' && window._currentValidatorAlias)\n delete window._currentValidatorAlias;\n \n var errors = self[this['name']]['errors'] || {}; \n local.data[this.name] = self[this.name].value;\n \n if ( \n typeof(errors['isRequired']) == 'undefined'\n && this.value == ''\n && !/^false$/i.test(this.value) \n && this.value != 0 \n ||\n !errors['isRequired'] \n && this.value == ''\n && !/^false$/i.test(this.value)\n && this.value != 0\n ) {\n isValid = true;\n } else if (!errors['isRequired'] && typeof(this.value) == 'string' && this.value == '') {\n isValid = true;\n }\n \n if ( !isValid && /^(true|false)$/i.test(condition) ) { // because it can be evaluated on backend validation\n isValid = condition;\n } else if (!isValid) {\n var re = null, flags = null;\n // Fixed on 2021-03-13: $variable now replaced with real value beafore validation\n if ( /[\\!\\=>\\>\\<a-z 0-9]+/i.test(condition) ) {\n var variables = condition.match(/\\${0}[-_,.\\[\\]a-z0-9]+/ig); // without space(s) \n if (variables && variables.length > 0) {\n var compiledCondition = condition;\n for (var i = 0, len = variables.length; i < len; ++i) {\n // $varibale comparison\n if ( typeof(self[ variables[i] ]) != 'undefined' && variables[i]) {\n re = new RegExp(\"\\\\$\"+ variables[i] +\"(?!\\\\S+)\", \"g\");\n if ( self[ variables[i] ].value == \"\" ) {\n compiledCondition = compiledCondition.replace(re, '\"\"');\n } else if ( typeof(self[ variables[i] ].value) == 'string' ) {\n compiledCondition = compiledCondition.replace(re, '\"'+ self[ variables[i] ].value +'\"');\n } else {\n compiledCondition = compiledCondition.replace(re, self[ variables[i] ].value);\n }\n }\n }\n \n try {\n // security checks\n compiledCondition = compiledCondition.replace(/(\\(|\\)|return)/g, '');\n if ( /^\\//.test(compiledCondition) ) {\n isValid = eval(compiledCondition + '.test(\"' + this.value + '\")')\n } else {\n isValid = eval(compiledCondition)\n }\n \n } catch (err) {\n throw new Error(err.stack||err.message)\n }\n }\n } else if ( condition instanceof RegExp ) {\n\n isValid = condition.test(this.value) ? true : false;\n\n } else if( typeof(condition) == 'boolean') {\n\n isValid = (condition) ? true : false;\n\n } else {\n try {\n // TODO - motif /gi to pass to the second argument\n if ( /\\/(.*)\\//.test(condition) ) {\n re = condition.match(/\\/(.*)\\//).pop();\n flags = condition.replace('/' + re + '/', '');\n\n isValid = new RegExp(re, flags).test(this.value)\n } else {\n isValid = eval(condition);\n }\n \n //valid = new RegExp(condition.replace(/\\//g, '')).test(this.value)\n } catch (err) {\n throw new Error(err.stack||err.message)\n }\n }\n }\n\n if (!isValid) {\n errors[alias] = replace(this.error || errorMessage || local.errorLabels[alias], this);\n if ( typeof(errorStack) != 'undefined' )\n errors['stack'] = errorStack;\n }\n // if error tagged by a previous vlaidation, remove it when isValid == true \n else if ( isValid && typeof(errors[alias]) != 'undefined' ) {\n delete errors[alias];\n //delete errors['stack'];\n }\n\n this.valid = isValid;\n if ( errors.count() > 0 )\n this['errors'] = errors;\n\n \n return self[this.name]\n }\n \n self[el]['set'] = function(value) {\n this.value = local['data'][this.name] = value;\n // html \n this.target.setAttribute('value', value);\n // Todo : select and radio case to apply change\n \n return self[this.name]\n }\n\n self[el]['isEmail'] = function() {\n\n\n this.value = local['data'][this.name] = (this.value) ? this.value.toLowerCase() : this.value;\n // Apply on current field upper -> lower\n if ( \n isGFFCtx\n && this.target\n && this.target.value != '' \n && /[A-Z]+/.test(this.target.value) \n ) {\n this.target.value = this.value;\n }\n \n\n var rgx = /^(([^<>()[\\]\\\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n var isValid = rgx.test(this['value']) ? true : false;\n var errors = self[this['name']]['errors'] || {};\n\n if ( !errors['isRequired'] && this.value == '' ) {\n isValid = true;\n }\n\n if (!isValid) {\n errors['isEmail'] = replace(this['error'] || local.errorLabels['isEmail'], this)\n }\n // if error tagged by a previous vlaidation, remove it when isValid == true \n else if ( isValid && typeof(errors['isEmail']) != 'undefined' ) {\n delete errors['isEmail'];\n //delete errors['stack'];\n }\n\n this.valid = isValid;\n\n if ( errors.count() > 0 )\n this['errors'] = errors;\n\n return self[this['name']]\n }\n\n self[el]['isJsonWebToken'] = function() {\n\n\n this.value = local['data'][this.name] = (this.value) ? this.value.toLowerCase() : this.value;\n // Apply on current field upper -> lower\n if ( \n isGFFCtx\n && this.target\n && this.target.value != '' \n && /[A-Z]+/.test(this.target.value) \n ) {\n this.target.value = this.value;\n }\n\n var rgx = /^[A-Za-z0-9-_=]+\\.[A-Za-z0-9-_=]+\\.?[A-Za-z0-9-_.+/=]*$/;\n var isValid = rgx.test(this['value']) ? true : false;\n var errors = self[this['name']]['errors'] || {};\n\n if ( !errors['isRequired'] && this.value == '' ) {\n isValid = true;\n }\n\n if (!isValid) {\n errors['isJsonWebToken'] = replace(this['error'] || local.errorLabels['isJsonWebToken'], this)\n }\n // if error tagged by a previous vlaidation, remove it when isValid == true \n else if ( isValid && typeof(errors['isJsonWebToken']) != 'undefined' ) {\n delete errors['isJsonWebToken'];\n //delete errors['stack'];\n }\n\n this.valid = isValid;\n\n if ( errors.count() > 0 )\n this['errors'] = errors;\n\n return self[this['name']]\n }\n \n /**\n * Check if boolean and convert to `true/false` booloean if value is a string or a number\n * Will include `false` value if isRequired\n * */\n self[el]['isBoolean'] = function() {\n var val = null\n , errors = self[this['name']]['errors'] || {}\n ;\n\n if ( errors['isRequired'] && this.value == false) {\n isValid = true;\n delete errors['isRequired'];\n this['errors'] = errors;\n }\n\n switch(this.value) {\n case 'true':\n case true:\n case 1:\n val = this.value = local.data[this.name] = true;\n break;\n case 'false':\n case false:\n case 0:\n val = this.value = local.data[this.name] = false;\n break;\n }\n \n var isValid = (val !== null) ? true : false;\n\n if (!isValid) {\n errors['isBoolean'] = replace(this.error || local.errorLabels['isBoolean'], this)\n }\n // if error tagged by a previous vlaidation, remove it when isValid == true \n else if ( isValid && typeof(errors['isBoolean']) != 'undefined' ) {\n delete errors['isBoolean'];\n //delete errors['stack'];\n }\n\n this.valid = isValid;\n if ( errors.count() > 0 )\n this['errors'] = errors;\n\n return self[this.name]\n }\n\n /**\n * Check if value is an a Number.\n * - valid if a number is found\n * - cast into a number if a string is found\n * - if string is blank, no transformation will be done: valid if not required\n *\n * @param {number} minLength\n * @param {number} maxLength\n *\n * @returns {object} result\n * */\n self[el]['isNumber'] = function(minLength, maxLength) {\n var val = this.value\n , len = 0\n , isValid = false\n , isMinLength = true\n , isMaxLength = true\n , errors = self[this['name']]['errors'] || {}\n ;\n \n // test if val is a number\n try {\n // if val is a string replaces comas by points\n if ( typeof(val) == 'string' && /\\,|\\./g.test(val) ) {\n val = local.data[this.name] = this.value = parseFloat( val.replace(/,/g, '.').replace(/\\s+/g, '') );\n } else if ( typeof(val) == 'string' && val != '') {\n val = local.data[this.name] = this.value = parseInt( val.replace(/\\s+/g, '') );\n }\n\n } catch (err) {\n errors['isNumber'] = replace(this.error || local.errorLabels['isNumber'], this);\n this.valid = false;\n if ( errors.count() > 0 )\n this['errors'] = errors;\n }\n\n if ( +val === +val ) {\n isValid = true;\n if ( !errors['isRequired'] && val != '' ) {\n len = val.toString().length;\n // if so also test max and min length if defined\n if (minLength && typeof(minLength) == 'number' && len < minLength) {\n isMinLength = false;\n this['size'] = minLength;\n }\n if (maxLength && typeof(maxLength) == 'number' && len > maxLength) {\n isMaxLength = false;\n this['size'] = maxLength;\n }\n }\n }\n\n // if val is invalid return error message\n if ( !isValid || !isMinLength || !isMaxLength ) {\n\n if ( !isValid )\n errors['isNumber'] = replace(this.error || local.errorLabels['isNumber'], this);\n if ( !isMinLength || !isMaxLength ) {\n if ( !isMinLength )\n errors['isNumberLength'] = replace(this.error || local.errorLabels['isNumberMinLength'], this);\n if ( !isMaxLength )\n errors['isNumberLength'] = replace(this.error || local.errorLabels['isNumberMaxLength'], this);\n if ( minLength === maxLength )\n errors['isNumberLength'] = replace(this.error || local.errorLabels['isNumberLength'], this);\n }\n\n isValid = false;\n }\n // if error tagged by a previous vlaidation, remove it when isValid == true \n if ( isValid && typeof(errors['isNumberLength']) != 'undefined') {\n delete errors['isNumberLength'];\n }\n\n this.valid = isValid;\n val = this.value = local.data[this.name] = ( val != '' ) ? Number(val) : val;\n if ( errors.count() > 0 )\n this['errors'] = errors;\n\n return self[this.name]\n }\n\n self[el]['toInteger'] = function() {\n var val = this.value\n , errors = self[this['name']]['errors'] || {}\n ;\n\n if (!val) {\n return self[this.name]\n } else {\n try {\n //val = this.value = local.data[this.name] = ~~(val.match(/[0-9]+/g).join(''));\n val = this.value = local.data[this.name] = Math.round(val);\n } catch (err) {\n\n errors['toInteger'] = replace(this.error || local.errorLabels['toInteger'], this);\n this.valid = false;\n if ( errors.count() > 0 )\n this['errors'] = errors;\n }\n\n }\n\n return self[this.name]\n }\n\n self[el]['isInteger'] = function(minLength, maxLength) {\n var val = this.value\n , isValid = false\n , isMinLength = true\n , isMaxLength = true\n , errors = self[this['name']]['errors'] || {}\n ;\n\n // test if val is a number\n if ( +val === +val && val % 1 === 0 ) {\n isValid = true;\n if ( !errors['isRequired'] && val != '' ) {\n // if so also test max and min length if defined\n if (minLength && typeof(minLength) == 'number' && val.length < minLength) {\n isMinLength = false;\n this['size'] = minLength;\n }\n if (maxLength && typeof(maxLength) == 'number' && val.length > maxLength) {\n isMaxLength = false;\n this['size'] = maxLength;\n }\n }\n }\n // if val is invalid return error message\n if ( !isValid || !isMinLength || !isMaxLength ) {\n\n if ( !isValid )\n errors['isInteger'] = replace(this.error || local.errorLabels['isInteger'], this);\n\n if ( !isMinLength || !isMaxLength ) {\n\n if ( !isMinLength ) {\n errors['isIntegerLength'] = replace(this.error || local.errorLabels['isIntegerMinLength'], this);\n isValid = false;\n }\n\n if ( !isMaxLength ) {\n errors['isIntegerLength'] = replace(this.error || local.errorLabels['isIntegerMaxLength'], this);\n isValid = false;\n }\n\n if ( minLength === maxLength ) {\n errors['isIntegerLength'] = replace(this.error || local.errorLabels['isIntegerLength'], this);\n isValid = false;\n }\n }\n }\n\n this.valid = isValid;\n val = this.value = local.data[this.name] = Number(val);\n\n if ( errors.count() > 0 )\n this['errors'] = errors;\n\n return self[this.name]\n }\n\n\n self[el]['toFloat'] = function(decimals) {\n if ( typeof(this.value) == 'string' ) {\n this.value = this.value.replace(/\\s+/g, '');\n if ( /\\,/.test(this.value) && !/\\./.test(this.value) ) {\n this.value = this.value.replace(/\\,/g,'.');\n //local.data[this.name] = this.value;\n // if (isGFFCtx) {\n // //this.target.setAttribute('value', this.value);\n // document.getElementById(this.target.id).value = this.value;\n // //triggerEvent(gina, this.target, 'change', self[this['name']]);\n // }\n \n } else {\n this.value = this.value.replace(/\\,/g,'');\n }\n }\n\n var val = local.data[this.name] = this.value\n , errors = self[this['name']]['errors'] || {}\n , isValid = true\n ;\n\n if (decimals) {\n this['decimals'] = parseInt(decimals)\n } else if ( typeof(this['decimals']) == 'undefined' ) {\n this['decimals'] = 2\n }\n\n if (!val) {\n return self[this.name]\n } else {\n if ( this['isNumber']().valid ) {\n try {\n\n if ( !Number.isFinite(val) ) {\n val = this.value = local.data[this.name] = new Number(parseFloat(val.match(/[0-9.,]+/g).join('').replace(/,/, '.')));// Number <> number\n }\n if (isGFFCtx)\n this.target.setAttribute('value', val);\n } catch(err) {\n isValid = false;\n errors['toFloat'] = replace(this.error || local.errorLabels['toFloat'], this);\n this.valid = false;\n if ( errors.count() > 0 )\n this['errors'] = errors;\n }\n } else {\n isValid = false;\n errors['toFloat'] = replace(this.error || local.errorLabels['toFloatNAN'], this)\n }\n }\n\n if (this['decimals'] && val && !errors['toFloat']) {\n this.value = local.data[this.name] = parseFloat(this.value.toFixed(this['decimals']));\n }\n\n this.valid = isValid;\n if ( errors.count() > 0 )\n this['errors'] = errors;\n\n return self[this.name]\n }\n\n /**\n * Check if value is float. No transformation is done here.\n * Can be used in combo preceded by *.toFloat(2) to transform data if needed:\n * 1 => 1.0\n * or\n * 3 500,5 => 3500.50\n *\n *\n * @param {number} [ decimals ]\n *\n * TODO - decimals transformation\n * */\n self[el]['isFloat'] = function(decimals) {\n\n if ( typeof(this.value) == 'string' ) {\n this.value = this.value.replace(/\\s+/g, '');\n }\n\n var val = local.data[this.name] = this.value\n , isValid = false\n , errors = self[this['name']]['errors'] || {}\n ;\n\n\n if ( typeof(val) == 'string' && /\\./.test(val) && Number.isFinite( Number(val) ) ) {\n isValid = true\n }\n\n // if string replaces comas by points\n if (typeof(val) == 'string' && /,/g.test(val)) {\n val = this.value = local.data[this.name] = Number(val.replace(/,/g, '.'))\n }\n\n // test if val is strictly a float\n if ( Number(val) === val && val % 1 !== 0 ) {\n this.value = local.data[this.name] = Number(val);\n isValid = true\n } else {\n isValid = false\n }\n\n if ( !errors['isRequired'] && this.value == '' ) {\n isValid = true\n }\n\n if (!isValid) {\n errors['isFloat'] = replace(this.error || local.errorLabels['isFloat'], this)\n }\n\n this.valid = isValid;\n if ( errors.count() > 0 )\n this['errors'] = errors;\n\n return self[this.name]\n }\n\n self[el]['isRequired'] = function(isApplicable) {\n\n if ( typeof(isApplicable) == 'boolean' && !isApplicable ) {\n\n this.valid = true;\n \n // is in excluded ?\n var excludedIndex = local.excluded.indexOf(this.name);\n if ( excludedIndex > -1 ) {\n local.excluded.splice(excludedIndex, 1);\n }\n\n return self[this.name]\n }\n\n // radio group case\n if ( \n isGFFCtx \n && this.target \n && this.target.tagName == 'INPUT' \n && typeof(this.target.type) != 'undefined' \n && this.target.type == 'radio' \n ) {\n var radios = document.getElementsByName(this.name);\n for (var i = 0, len = radios.length; i < len; ++i) {\n if (radios[i].checked) {\n if ( /true|false/.test(radios[i].value) ) {\n this.value = local.data[this.name] = ( /true/.test(radios[i].value) ) ? true : false\n } else {\n this.value = local.data[this.name] = radios[i].value;\n }\n\n this.valid = true;\n break;\n }\n }\n }\n\n\n var isValid = ( typeof(this.value) != 'undefined' && this.value != null && this.value != '' && !/^\\s+/.test(this.value) ) ? true : false;\n var errors = self[this['name']]['errors'] || {};\n\n\n if (!isValid) {\n errors['isRequired'] = replace(this.error || local.errorLabels['isRequired'], this)\n }\n // if error tagged by a previous vlaidation, remove it when isValid == true \n else if ( isValid ) {\n if (typeof(errors['isRequired']) != 'undefined' )\n delete errors['isRequired'];\n //delete errors['stack'];\n // if ( typeof(self[this.name]['errors']) != 'undefined' && typeof(self[this.name]['errors']['isRequired']) != 'undefined' )\n // delete self[this.name]['errors']['isRequired'];\n }\n\n this.valid = isValid;\n if (errors.count() > 0)\n this['errors'] = errors;\n\n return self[this.name]\n }\n /**\n *\n * isString() -> validate if value is string\n * isString(10) -> validate if value is at least 10 chars length\n * isString(0, 45) -> no minimum length, but validate if value is maximum 45 chars length\n * NB.:\n * In your JSON rule ;\n * {\n * \"password\": {\n * \"isRequired\": true,\n * \n * \"isString\": true // Means that we just want a string and we don't care of its length\n * // OR\n * \"isString\": 7 // Means at least 7 chars length\n * // OR\n * \"isString\": [7, 40] // Means at least 7 chars length and maximum 40 chars length\n * // OR\n * \"isString\": [7] // Means is strickly equal to 7 chars length, same as [7,7]\n * }\n * }\n * @param {number|undefined} [ minLength ]\n * @param {number} [ maxLength ]\n * */\n self[el]['isString'] = function(minLength, maxLength) {\n\n var val = local.data[this.name] = this.value\n , isValid = false\n , isMinLength = true\n , isMaxLength = true\n , errors = self[this['name']]['errors'] || {}\n ;\n\n\n // test if val is a string\n if ( typeof(val) == 'string' ) {\n //isValid = true;\n\n if ( !errors['isRequired'] && val != '' ) {\n isValid = true;\n // if so also test max and min length if defined\n if (minLength && typeof(minLength) == 'number' && val.length < minLength) {\n isMinLength = false;\n this['size'] = minLength;\n }\n if (maxLength && typeof(maxLength) == 'number' && val.length > maxLength) {\n isMaxLength = false;\n this['size'] = maxLength;\n }\n }\n\n }\n\n // if val is invalid return error message\n if (!isValid || !isMinLength || !isMaxLength ) {\n\n if (!isValid && errors['isRequired'] && val == '') {\n isValid = false;\n errors['isString'] = replace(this['error'] || local.errorLabels['isString'], this);\n } else if (!isValid && !errors['isRequired']) {\n isValid = true;\n }\n\n if ( !isMinLength || !isMaxLength) {\n isValid = false;\n\n if ( !isMinLength )\n errors['isStringLength'] = replace(this['error'] || local.errorLabels['isStringMinLength'], this);\n if ( !isMaxLength )\n errors['isStringLength'] = replace(this['error'] || local.errorLabels['isStringMaxLength'], this);\n if (minLength === maxLength)\n errors['isStringLength'] = replace(this['error'] || local.errorLabels['isStringLength'], this);\n }\n\n }\n\n this.valid = isValid;\n if ( errors.count() > 0 ) {\n this['errors'] = errors;\n }\n\n return self[this.name]\n }\n\n /**\n * Check if date\n *\n * @param {string|boolean} [mask] - by default \"yyyy-mm-dd\"\n *\n * @returns {date} date - extended by gina::utils::dateFormat; an adaptation of Steven Levithan's code\n * */\n self[el]['isDate'] = function(mask) { \n var val = this.value\n , isValid = false\n , errors = self[this['name']]['errors'] || {}\n , m = null\n , date = null\n ;\n // Default validation on livecheck & invalid init value\n if (!val || val == '' || /NaN|Invalid Date/i.test(val) ) { \n if ( /NaN|Invalid Date/i.test(val) ) {\n console.warn('[FormValidator::isDate] Provided value for field `'+ this.name +'` is not allowed: `'+ val +'`');\n errors['isDate'] = replace(this.error || local.errorLabels['isDate'], this);\n \n }\n this.valid = isValid;\n if ( errors.count() > 0 )\n this['errors'] = errors; \n \n return self[this.name];\n }\n \n if ( \n typeof(mask) == 'undefined'\n ||\n typeof(mask) != 'undefined' && /true/i.test(mask)\n ) {\n mask = \"yyyy-mm-dd\"; // by default\n }\n \n if (val instanceof Date) {\n date = val.format(mask);\n } else {\n \n try {\n m = mask.match(/[^\\/\\- ]+/g);\n } catch (err) {\n throw new Error('[FormValidator::isDate] Provided mask not allowed: `'+ mask +'`');\n }\n \n try {\n val = val.match(/[^\\/\\- ]+/g);\n var dic = {}, d, len;\n for (d=0, len=m.length; d<len; ++d) {\n dic[m[d]] = val[d]\n }\n var formatedDate = mask;\n for (var v in dic) {\n formatedDate = formatedDate.replace(new RegExp(v, \"g\"), dic[v])\n }\n } catch (err) {\n throw new Error('[FormValidator::isDate] Provided value not allowed: `'+ val +'`' + err);\n }\n \n\n date = this.value = local.data[this.name] = new Date(formatedDate);\n \n if ( /Invalid Date/i.test(date) || date instanceof Date === false ) {\n if ( !errors['isRequired'] && this.value == '' ) {\n isValid = true\n } else {\n errors['isDate'] = replace(this.error || local.errorLabels['isDate'], this);\n }\n\n this.valid = isValid;\n if ( errors.count() > 0 )\n this['errors'] = errors;\n\n return self[this.name]\n }\n isValid = true;\n }\n\n this.valid = isValid;\n\n return date\n }\n\n /**\n * Formating date using DateFormatHelper\n * Check out documentation in the helper source: `utils/helpers/dateFormat.js`\n * e.g.:\n * d.start\n * .isDate('dd/mm/yyyy')\n * .format('isoDateTime');\n *\n *\n * */\n self[el]['format'] = function(mask, utc) {\n var val = this.value;\n if (!val) return self[this.name];\n\n return val.format(mask, utc)\n };\n\n /**\n * Set flash\n *\n * @param {str} flash\n * */\n self[el]['setFlash'] = function(regex, flash) {\n if ( typeof(flash) != 'undefined' && flash != '') {\n this.error = flash\n }\n return self[this.name]\n }\n\n /**\n * Set label\n *\n * @param {str} label\n * */\n self[el]['setLabel'] = function(label) {\n if ( typeof(label) != 'undefined' && label != '') {\n this.label = label\n }\n return self[this.name]\n }\n \n /**\n * Trim when string starts or ends with white space(s)\n *\n * @param {str} trimmed off string\n * */\n self[el]['trim'] = function(isApplicable) {\n if ( typeof(isApplicable) == 'boolean' && isApplicable ) {\n //if ( typeof(this.value) == 'string' ) {\n this.value = this.value.replace(/^\\s+|\\s+$/, '');\n local.data[this.name] = local.data[this.name] = this.value;\n //}\n return self[this.name]\n }\n }\n\n /**\n * Exclude when converting back to datas\n *\n * @returns {object} data\n * */\n self[el]['exclude'] = function(isApplicable) {\n\n if ( typeof(isApplicable) == 'boolean' && !isApplicable ) {\n \n if ( /^true|false$/i.test(this.value)) {\n this.value = (/^true$/i.test(this.value)) ? true : false;\n local.data[this.name] = this.value;\n } \n\n return self[this.name]\n }\n this.isExcluded = false;\n // list field to be purged\n if ( local.excluded.indexOf(this.name) < 0) {\n local.excluded.push(this.name);\n this.isExcluded = true;\n }\n \n \n // remove existing errors\n return self[this.name];\n }\n /**\n * Validation through API call\n * Try to put this rule at the end to prevent sending\n * a request to the remote host if previous rules failed\n */\n self[el]['query'] = query;\n \n \n self[el]['getValidationContext'] = function() {\n return {\n 'isGFFCtx' : isGFFCtx,\n 'self' : self,\n 'local' : local,\n 'replace' : replace\n }\n }\n // Merging user validators\n // To debug, open inspector and look into `Extra Scripts` \n if ( hasUserValidators() ) {\n var userValidator = null, filename = null;\n try { \n for (let v in gina.forms.validators) {\n filename = '/validators/'+ v + '/main.js';\n // setting default local error\n local.errorLabels[v] = 'Condition not satisfied';\n // converting Buffer to string\n if ( isGFFCtx ) {\n //userValidatorError = String.fromCharCode.apply(null, new Uint16Array(gina.forms.validators[v].data));\n userValidator = bufferToString(gina.forms.validators[v].data); // ok\n var passedContext = 'var validationContext = this.getValidationContext(),isGFFCtx = validationContext.isGFFCtx,self = validationContext.self,local = validationContext.local,replace = validationContext.replace;';\n userValidator = userValidator.replace(/(\\)\\s+\\{|\\)\\{){1}/, '$&\\n\\t'+ passedContext);\n \n //userValidator += '\\n//#sourceURL='+ v +'.js';\n } else {\n userValidator = gina.forms.validators[v].toString();\n }\n \n self[el][v] = eval('(' + userValidator + ')\\n//# sourceURL='+ v +'.js');\n //self[el][v] = Function('errorMessage', 'errorStack', userValidator);\n }\n } catch (userValidatorError) {\n throw new Error('[UserFormValidator] Could not evaluate: `'+ filename +'`\\n'+userValidatorError.stack);\n }\n }\n } // EO addField(el, value) \n \n \n for (let el in self) { \n // Adding fields & validators to context\n addField(el, self[el]);\n }\n \n self['addField'] = function(el, value) {\n if ( typeof(self[el]) != 'undefined' ) {\n return\n }\n addField(el, value);\n };\n \n \n // self['getExcludedFields'] = function() {\n // return local.excluded;\n // };\n\n /**\n * Check if errors found during validation\n *\n * @returns {boolean}\n * */\n self['isValid'] = function() {\n return (self['getErrors']().count() > 0) ? false : true;\n }\n self['setErrors'] = function(errors) {\n if (!errors) {\n return {}\n }\n for (var field in self) {\n if ( typeof(self[field]) != 'object' ) {\n continue\n }\n // if ( typeof(self[field]['errors']) == 'undefined' || self[field]['errors'].count() == 0 ) {\n // delete errors[field];\n // continue;\n // }\n // if ( typeof(errors[field]) == 'undefined' ) {\n // continue;\n // }\n for (var r in self[field]) {\n // no error for the current field rule\n if ( \n typeof(errors[field]) != 'object'\n ||\n typeof(errors[field][r]) == 'undefined'\n ) {\n continue;\n }\n \n \n if ( \n typeof(self[field].valid) != 'undefined' \n && /^true$/i.test(self[field].valid) \n ) {\n delete errors[field][r];\n continue;\n }\n \n \n if ( typeof( self[field]['errors']) == 'undefined' ) {\n self[field]['errors'] = {}\n }\n \n self[field]['errors'][r] = errors[field][r]; \n }\n \n // if field does not have errors, remove errors[field]\n if ( \n typeof(self[field]['errors']) == 'undefined'\n && typeof(errors[field]) != 'undefined'\n ||\n typeof(self[field]['errors']) != 'undefined'\n && self[field]['errors'].count() == 0\n && typeof(errors[field]) != 'undefined'\n ) {\n delete errors[field];\n continue;\n }\n }\n return errors;\n }\n /**\n * getErrors\n * NB.: This portion is shared between the front & the back\n * \n * @param {string} [fieldName]\n * \n * @returns errors\n */\n self['getErrors'] = function(fieldName) {\n var errors = {};\n \n if ( typeof(fieldName) != 'undefined' ) {\n if ( typeof(self[fieldName]) != 'undefined' && self[fieldName] && typeof(self[fieldName]['errors']) != 'undefined' && self[fieldName]['errors'].count() > 0 ) {\n errors[fieldName] = self[fieldName]['errors'];\n } \n return errors\n }\n \n for (var field in self) {\n if ( \n typeof(self[field]) != 'object'\n ) {\n continue;\n }\n \n if ( typeof(self[field]['errors']) != 'undefined' ) {\n if ( self[field]['errors'].count() > 0)\n errors[field] = self[field]['errors'];\n }\n }\n \n return errors\n }\n\n self['toData'] = function() {\n\n // cleaning data\n if (local.excluded.length > 0) {\n for (var i = 0, len = local.excluded.length; i < len; ++i) {\n if ( typeof(local.data[ local.excluded[i] ]) != 'undefined' ) {\n delete local.data[ local.excluded[i] ]\n }\n }\n }\n // local.data = JSON.parse(JSON.stringify(local.data).replace(/\\\"(true|false)\\\"/gi, '$1'))\n return local.data\n }\n \n /**@js_externs replace*/\n var replace = function(target, fieldObj) {\n var keys = target.match(/%[a-z]+/gi);\n if (keys) {\n for (var k = 0, len = keys.length; k < len; ++k) {\n target = target.replace(new RegExp(keys[k], 'g'), fieldObj[local.keys[keys[k]]])\n }\n }\n\n return target\n }\n\n self['setErrorLabels'] = function (errorLabels) {\n if ( typeof(errorLabels) != 'undefined') {\n local.errorLabels = merge(errorLabels, local.errorLabels)\n }\n }\n\n return self\n};\n\nif ( ( typeof(module) !== 'undefined' ) && module.exports ) {\n // Publish as node.js module\n module.exports = FormValidatorUtil\n} else if ( typeof(define) === 'function' && define.amd) {\n // Publish as AMD module\n define('utils/form-validator',[],function() { return FormValidatorUtil })\n};\n",
|
|
41
|
-
"/*\n * This file is part of the gina package.\n * Copyright (c) 2009-2022 Rhinostone <contact@gina.io>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n/**\n * Routing\n *\n * @package Gina.Lib\n * @namespace Gina.Lib.Routing\n * @author Rhinostone <contact@gina.io>\n * */\n\nfunction Routing() {\n\n var isGFFCtx = ((typeof (module) !== 'undefined') && module.exports) ? false : true;\n var self = {\n allowedMethods: ['get', 'post', 'put', 'delete'],\n reservedParams: ['controle', 'file','title', 'namespace', 'path'],\n notFound: {}\n }; \n \n self.allowedMethodsString = self.allowedMethods.join(',');\n \n // loading utils & plugins\n var plugins = null, inherits = null, merge = null, Validator = null, fs = null, promisify = null;\n if (!isGFFCtx) {\n fs = require('fs');\n promisify = require('util').promisify;\n inherits = require('../../inherits');\n merge = require('../../merge');\n plugins = require(__dirname+'/../../../core/plugins') || getContext('gina').plugins;\n Validator = plugins.Validator;\n \n } \n // BO - In case of partial rendering whithout handler defined for the partial\n else {\n if ( !merge || typeof(merge) != 'function' ) {\n var merge = require('utils/merge');\n }\n if ( !Validator || typeof(Validator) != 'function' ) {\n var Validator = require('utils/form-validator');\n }\n } \n // EO - In case of partial rendering whithout handler defined for the partial\n \n /**\n * Get url props\n * Used to retrieve additional properties for routes with redirect flag for example\n * \n * @param {string} [bundle]\n * @param {string} [env] \n * \n * @returns {object} urlProps - { .host, .hostname, .webroot }\n */\n self.getUrlProps = function(bundle, env) {\n var config = null, urlProps = {}, _route = null;\n if (isGFFCtx) {\n // TODO - add support to get from env\n config = window.gina.config;\n // by default\n urlProps.hostname = config.hostname;\n if ( typeof(bundle) != 'undefined' ) {\n // get from webroot\n _route = routing.getRoute('webroot@'+ bundle);\n urlProps.hostname = _route.hostname;\n urlProps.host = _route.host;\n urlProps.webroot = _route.webroot;\n } \n } else {\n config = getContext('gina').config;\n if ( typeof(getContext('argvFilename')) != 'undefined' ) {\n config.getRouting = getContext('gina').Config.instance.getRouting\n }\n if ( typeof(bundle) == 'undefined' ) {\n bundle = config.bundle;\n }\n if ( typeof(env) == 'undefined' ) {\n env = config.env;\n }\n \n urlProps.hostname = config.envConf[bundle][env].hostname;\n urlProps.host = config.envConf[bundle][env].host;\n urlProps.webroot = config.envConf[bundle][env].server.webroot;\n }\n \n return urlProps;\n }\n \n /**\n * Load bundle routing configuration\n * \n * @param {object} options\n * {\n * isStadalone: false,\n * bundle: 'default', // bundle's name\n * wroot: '/', // by default\n * \n * }\n * \n */\n // self.loadBundleRoutingConfiguration = function(options, filename) {\n \n // }\n \n /**\n * Get routing\n * \n * @param {string} [bundle]\n */\n // self.getRouting = function(bundle) {\n \n // }\n \n /**\n * Get reversed routing\n * \n * @param {string} [bundle]\n */\n // self.getReverseRouting = function(bundle) {\n \n // }\n\n /**\n * Compare urls\n *\n * @param {object} params - Route params containing the given url to be compared with\n * @param {string|array} url - routing.json url\n * @param {object} [request]\n * @param {object} [response] - only used for query validation\n * @param {object} [next] - only used for query validation\n *\n * @returns {object|false} foundRoute\n * */\n self.compareUrls = async function(params, url, request, response, next) {\n \n if ( typeof(request) == 'undefined' ) {\n request = { routing: {} };\n }\n // Sample debug break for specific rule\n // if ( params.rule == 'my-specific-rule@bundle' ) {\n // console.debug('passed '+ params.rule);\n // }\n if ( /\\,/.test(url) ) {\n var i = 0\n , urls = url.split(/\\,/g)\n , len = urls.length\n , foundRoute = {\n past: false,\n request: request\n };\n\n\n while (i < len && !foundRoute.past) {\n foundRoute = await parseRouting(params, urls[i], request, response, next);\n ++i;\n }\n\n return foundRoute;\n } else {\n return await parseRouting(params, url, request, response, next);\n }\n };\n\n /**\n * Check if rule has params\n *\n * @param {string} pathname\n * @returns {boolean} found\n *\n * @private\n * */\n var hasParams = function(pathname) {\n return (/:/.test(pathname)) ? true : false;\n };\n\n /**\n * Parse routing for mathcing url\n *\n * @param {object} params - `params` is the same `request.routing` that can be retried in controller with: req.routing\n * @param {string} url\n * @param {object} request\n * @param {object} [response] - Only used for query validation\n * @param {object} [next] - Only used for query validation\n *\n * @returns {object} foundRoute\n *\n * */\n var parseRouting = async function(params, url, request, response, next) {\n \n // Sample debug break for specific rule\n // if ( params.rule == 'my-specific-rule@bundle' ) {\n // console.debug('passed '+ params.rule);\n // }\n \n var uRe = params.url.split(/\\//)\n , uRo = url.split(/\\//)\n , uReCount = 0\n , uRoCount = 0\n , maxLen = uRo.length\n , score = 0\n , foundRoute = {}\n , i = 0\n , method = request.method.toLowerCase()\n ;\n \n // TODO - remove comments\n // when requirement is not listed but still validated\n // if ( \n // typeof(params.requirements) != 'undefined' \n // && method == params.method.toLowerCase()\n // //&& /validator\\:\\:/.test(JSON.stringify(params.requirements))\n // ) {\n \n // var requiremements = Object.getOwnPropertyNames(params.requirements);\n // var r = 0;\n // // In order to filter variables\n // var uRoVars = uRo.join(',').match(/\\:[-_a-z0-9]+/g);\n // // var uRoVarCount = (uRoVars) ? uRoVars.length : 0;\n // while ( r < requiremements.length ) {\n \n // // if not listed, but still needing validation\n // if ( \n // typeof(params.param[ requiremements[r] ]) == 'undefined' \n // && /^validator\\:\\:/i.test(params.requirements[ requiremements[r] ])\n // && typeof(request[method][ requiremements[r] ])\n // ) {\n // if (uRo.length != uRe.length) {\n // // r++; \n // // continue;\n // break;\n // }\n // // updating uRoVars\n // uRoVars = uRo.join(',').match(/\\:[-_a-z0-9]+/g);\n // /**\n // * \"requirements\" : {\n // * \"email\": \"validator::{ isEmail: true, isString: [7] }\"\n // * }\n // * \n // * e.g.: result = new Validator('routing', _data, null, {email: {isEmail: true, subject: \\\"Anything\\\"}} ).isEmail().valid;\n // */ \n // let regex = params.requirements[ requiremements[r] ];\n // let _data = {}, _ruleObj = {}, _rule = {};\n \n // try {\n // _ruleObj = JSON.parse(\n // regex.split(/::/).splice(1)[0]\n // .replace(/([^\\:\\\"\\s+](\\w+))\\:/g, '\"$1\":') // { query: { validIf: true }} => { \"query\": { \"validIf\": true }}\n // .replace(/([^\\:\\\"\\s+](\\w+))\\s+\\:/g, '\"$1\":') // note the space between `validIf` & `:` { query: { validIf : true }} => { \"query\": { \"validIf\": true }}\n // ); \n // } catch (err) {\n // throw err;\n // }\n \n // let key = requiremements[r];\n // // validator.query case\n // if (typeof(_ruleObj.query) != 'undefined' && typeof(_ruleObj.query.data) != 'undefined') {\n // _data = _ruleObj.query.data;\n // // filter _data vs uRoVars by removing from data those not present in uRoVars\n // for (let k in _data) {\n // if ( uRoVars.indexOf(_data[k]) < 0 ) {\n // delete _data[k]\n // }\n // }\n // for (let p = 0, pLen = uRo.length; p < pLen; p++) {\n // // :variable only\n // if (!/^\\:/.test(uRo[p])) continue;\n \n // let pName = uRo[p].replace(/^\\:/, '');\n // if ( pName != '' && typeof(uRe[p]) != 'undefined' ) {\n // _data[ pName ] = uRe[p];\n // // Updating params\n // if ( typeof(request.params[pName]) == 'undefined' ) {\n // // Set in case it is not found\n // request.params[pName] = uRe[p];\n // }\n // }\n // } \n // }\n // // normal case\n // _data = merge(_data, request[method]);\n \n // if ( typeof(_data[key]) == 'undefined' ) {\n // // init default value for unlisted variable/param\n // _data[key] = null;\n // }\n \n // _rule[key] = _ruleObj; \n // _validator = new Validator('routing', _data, null, _rule );\n \n // if (_ruleObj.count() == 0 ) {\n // console.error('Route validation failed '+ params.rule);\n // return false;\n // }\n \n // for (let rule in _ruleObj) {\n // let _result = null;\n // if (Array.isArray(_ruleObj[rule])) { // has args\n // _result = await _validator[key][rule].apply(_validator[key], _ruleObj[rule]);\n // } else {\n // _result = await _validator[key][rule](_ruleObj[rule], request, response, next);\n // }\n // //let condition = _ruleObj[rule].validIf.replace(new RegExp('\\\\$isValid'), _result.isValid);\n // // if ( eval(condition)) {\n // if ( !_result.isValid ) {\n // --score;\n // }\n // }\n // }\n // r++\n // }\n // }\n \n // attaching routing description for this request\n var paramMethod = params.method.toLowerCase();\n \n var hasAlreadyBeenScored = false;\n if ( \n typeof(params.requirements) != 'undefined'\n && /get|delete/i.test(method)\n && typeof(request[method]) != 'undefined'\n ||\n // GET request is in fact in this case a DELETE request\n typeof(params.requirements) != 'undefined'\n && /get/i.test(method)\n && /delete/i.test(paramMethod)\n ) { \n if ( /get/i.test(method) && /delete/i.test(paramMethod) ) {\n method = paramMethod;\n }\n // `delete` methods don't have a body\n // So, request.delete is {} by default\n if ( /^(delete)$/i.test(method) && uRe.length === uRo.length ) { \n // just in case\n if ( typeof(request[method]) == 'undefined' ) {\n request[method] = {};\n }\n for (let p = 0, pLen = uRo.length; p < pLen; p++) {\n if (uRe[p] === uRo[p]) { \n ++score; \n continue;\n }\n let _key = uRo[p].substr(1);\n if ( typeof(params.requirements[_key]) == 'undefined' ) {\n continue;\n }\n let condition = params.requirements[_key];\n if ( /^\\//.test(condition) ) {\n condition = condition.substr(1, condition.lastIndexOf('/')-1);\n } else if ( /^validator\\:\\:/.test(condition) && await fitsWithRequirements(uRo[p], uRe[p], params, request, response, next) ) {\n ++score;\n continue;\n }\n if (\n /^:/.test(uRo[p]) \n && typeof(condition) != 'undefined'\n && new RegExp(condition).test(uRe[p])\n ) {\n ++score; \n request[method][uRo[p].substr(1)] = uRe[p]; \n }\n }\n hasAlreadyBeenScored = true; \n } \n \n // Sample debug break for specific rule\n // if ( params.rule == 'my-specific-rule@bundle' ) {\n // console.debug('passed '+ params.rule);\n // }\n for (let p in request[method]) {\n if ( typeof(params.requirements[p]) != 'undefined' && uRo.indexOf(':' + p) < 0 ) {\n uRo[uRoCount] = ':' + p; \n ++uRoCount;\n \n uRe[uReCount] = request[method][p];\n ++uReCount;\n if (!hasAlreadyBeenScored && uRe.length === uRo.length)\n ++maxLen; \n }\n }\n }\n \n \n // Sample debug break for specific rule\n // if ( params.rule == 'my-specific-rule@bundle' ) {\n // console.debug('passed '+ params.rule);\n // }\n \n if (!hasAlreadyBeenScored && uRe.length === uRo.length) {\n \n for (; i < maxLen; ++i) {\n \n if (uRe[i] === uRo[i]) {\n ++score;\n }\n else if (score == i && hasParams(uRo[i]) && await fitsWithRequirements(uRo[i], uRe[i], params, request, response, next)) {\n ++score;\n }\n }\n }\n \n // This test is done to catch `validator::` rules under requirements\n if ( \n typeof(params.requirements) != 'undefined' \n && method == params.method.toLowerCase()\n && !hasAlreadyBeenScored\n && score >= maxLen\n ) {\n \n var requiremements = Object.getOwnPropertyNames(params.requirements);\n var r = 0;\n // In order to filter variables\n var uRoVars = uRo.join(',').match(/\\:[-_a-z0-9]+/g);\n // var uRoVarCount = (uRoVars) ? uRoVars.length : 0;\n while ( r < requiremements.length ) {\n // requirement name as `key`\n let key = requiremements[r];\n // if not listed, but still needing validation\n if ( \n typeof(params.param[ key ]) == 'undefined' \n && /^validator\\:\\:/i.test(params.requirements[ key ])\n ) {\n if (uRo.length != uRe.length) {\n // r++; \n // continue;\n break;\n }\n // updating uRoVars\n uRoVars = uRo.join(',').match(/\\:[-_a-z0-9]+/g);\n /**\n * \"requirements\" : {\n * \"email\": \"validator::{ isEmail: true, isString: [7] }\"\n * }\n * \n * e.g.: result = new Validator('routing', _data, null, {email: {isEmail: true, subject: \\\"Anything\\\"}} ).isEmail().valid;\n */ \n let regex = params.requirements[ key ];\n let _data = {}, _ruleObj = {}, _rule = {};\n \n try {\n _ruleObj = JSON.parse(\n regex.split(/::/).splice(1)[0]\n .replace(/([^\\:\\\"\\s+](\\w+))\\:/g, '\"$1\":') // { query: { validIf: true }} => { \"query\": { \"validIf\": true }}\n .replace(/([^\\:\\\"\\s+](\\w+))\\s+\\:/g, '\"$1\":') // note the space between `validIf` & `:` { query: { validIf : true }} => { \"query\": { \"validIf\": true }}\n ); \n } catch (err) {\n throw err;\n }\n \n // validator.query case\n if (typeof(_ruleObj.query) != 'undefined' && typeof(_ruleObj.query.data) != 'undefined') {\n _data = _ruleObj.query.data;\n // filter _data vs uRoVars by removing from data those not present in uRoVars\n for (let k in _data) {\n if ( uRoVars.indexOf(_data[k]) < 0 ) {\n delete _data[k]\n }\n }\n for (let p = 0, pLen = uRo.length; p < pLen; p++) {\n // :variable only\n if (!/^\\:/.test(uRo[p])) continue;\n \n let pName = uRo[p].replace(/^\\:/, '');\n if ( pName != '' && typeof(uRe[p]) != 'undefined' ) {\n _data[ pName ] = uRe[p];\n // Updating params\n if ( typeof(request.params[pName]) == 'undefined' ) {\n // Set in case if not found\n request.params[pName] = uRe[p];\n }\n }\n } \n }\n \n // If validator.query has data, _data should inherit from request data\n _data = merge(_data, JSON.clone(request[method]) || {} );\n // This test is to initialize query.data[key] to null by default\n if ( typeof(_data[key]) == 'undefined' ) {\n // init default value for unlisted variable/param\n _data[key] = null;\n }\n \n _rule[key] = _ruleObj; \n if (!isGFFCtx) {\n _validator = new Validator('routing', _data, null, _rule );\n } else {\n _validator = new Validator(_data);\n }\n \n if (_ruleObj.count() == 0 ) {\n console.error('Route validation failed '+ params.rule);\n --score;\n r++;\n continue;\n } \n // for each validation rule\n for (let rule in _ruleObj) {\n // updating query.data\n if (typeof(_ruleObj[rule].data) != 'undefined') {\n _ruleObj[rule].data = _data;\n }\n let _result = null;\n if (Array.isArray(_ruleObj[rule])) { // has args\n _result = await _validator[key][rule].apply(_validator[key], _ruleObj[rule]);\n } else {\n _result = await _validator[key][rule](_ruleObj[rule], request, response, next);\n } \n \n //let condition = _ruleObj[rule].validIf.replace(new RegExp('\\\\$isValid'), _result.isValid);\n // if ( eval(condition)) {\n if ( !_result.isValid ) {\n --score;\n if ( typeof(_result.error) != 'undefined' ) {\n throw _result.error;\n }\n }\n }\n }\n r++\n }\n }\n\n foundRoute.past = (score === maxLen) ? true : false;\n \n if (foundRoute.past) {\n // attaching routing description for this request\n //request.routing = params; // can be retried in controller with: req.routing\n // && replacing placeholders\n request.routing = checkRouteParams(params, request[method]);\n foundRoute.request = request;\n }\n \n\n return foundRoute;\n };\n\n /**\n * Fits with requiremements\n * This is for server side use only\n * http://en.wikipedia.org/wiki/Regular_expression\n *\n * @param {string} urlVar\n * @param {string} urlVal\n * @param {object} params\n *\n * @returns {boolean} true|false - `true` if it fits\n *\n * @private\n * */\n var fitsWithRequirements = async function(urlVar, urlVal, params, request, response, next) {\n // Sample debug break for specific rule\n // if ( params.rule == 'my-specific-rule@bundle' ) {\n // console.debug('passed '+ params.rule);\n // }\n //var isValid = new Validator('routing', { email: \"contact@gina.io\"}, null, {email: {isEmail: true}} ).isEmail().valid;\n var matched = -1\n , _param = urlVar.match(/\\:\\w+/g)\n , regex = new RegExp(urlVar, 'g')\n , re = null\n , flags = null\n , key = null\n , tested = false\n \n , _validator = null\n , _data = null\n , _ruleObj = null\n , _rule = null\n , rule = null\n , str = null\n // request method\n , requestMethod = request.method.toLowerCase()\n ;\n \n if (!_param.length) return false;\n\n // if custom path, path rewrite\n if (params.param.path && regex.test(params.param.path)) {\n params.param.path = params.param.path.replace(regex, urlVal);\n }\n \n // if custom namespace, namespace rewrite\n if (params.param.namespace && regex.test(params.param.namespace)) { \n params.param.namespace = params.param.namespace.replace(regex, urlVal); \n }\n \n // if custom file, file rewrite\n // if (params.param.file && regex.test(params.param.file)) { \n // params.param.file = params.param.file.replace(regex, urlVal); \n // }\n // file is handle like url replacement (path is like pathname)\n if (typeof (params.param.file) != 'undefined' && /:/.test(params.param.file)) {\n var _regex = new RegExp('(:'+urlVar+'/|:'+urlVar+'$)', 'g'); \n replacement.variable = urlVal; \n params.param.file = params.param.file.replace( _regex, replacement );\n }\n\n // if custom title, title rewrite\n if (params.param.title && regex.test(params.param.title)) { \n params.param.title = params.param.title.replace(regex, urlVal);\n }\n\n if (_param.length == 1) { // fast one\n \n re = new RegExp( _param[0]);\n matched = (_param.indexOf(urlVar) > -1) ? _param.indexOf(urlVar) : false;\n \n if (matched === false ) {\n // In order to support rules defined like :\n // { params.url } => `/section/:name/page:number`\n // { request.url } => `/section/plante/page4`\n //\n // with keys = [ \":name\", \":number\" ]\n \n if ( urlVar.match(re) ) {\n matched = 0;\n }\n }\n \n\n if (matched === false) return matched;\n // filter on method\n if (params.method.toLowerCase() !== requestMethod) return false;\n \n if ( typeof(request[requestMethod]) == 'undefined' ) {\n request[requestMethod] = {}\n }\n\n key = _param[matched].substr(1);\n // escaping `\\` characters\n // TODO - remove comment : all regex requirement must start with `/`\n //regex = ( /\\\\/.test(params.requirements[key]) ) ? params.requirements[key].replace(/\\\\/, '') : params.requirements[key];\n regex = params.requirements[key];\n if (/^\\//.test(regex)) {\n re = regex.match(/\\/(.*)\\//).pop();\n flags = regex.replace('/' + re + '/', ''); \n\n tested = new RegExp(re, flags).test(urlVal)\n } else if ( /^validator\\:\\:/.test(regex) && urlVal) {\n /**\n * \"requirements\" : {\n * \"id\" : \"/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\",\n * \"email\": \"validator::{ isEmail: true, isString: [7] }\"\n * }\n * \n * e.g.: tested = new Validator('routing', _data, null, {email: {isEmail: true, subject: \\\"Anything\\\"}} ).isEmail().valid;\n */ \n _data = {}; _ruleObj = {}; _rule = {}; str = ''; \n urlVar.replace( new RegExp('[^'+ key +']','g'), function(){ str += arguments[0] }); \n _data[key] = urlVal.replace( new RegExp(str, 'g'), '');\n try {\n //_ruleObj = JSON.parse(regex.split(/::/).splice(1)[0].replace(/([^\\W+ true false])+(\\w+)/g, '\"$&\"'));\n _ruleObj = JSON.parse(\n regex.split(/::/).splice(1)[0]\n .replace(/([^\\:\\\"\\s+](\\w+))\\:/g, '\"$1\":') // { query: { validIf: true }} => { \"query\": { \"validIf\": true }}\n .replace(/([^\\:\\\"\\s+](\\w+))\\s+\\:/g, '\"$1\":') // note the space between `validIf` & `:` { query: { validIf : true }} => { \"query\": { \"validIf\": true }}\n ); \n } catch (err) {\n throw err;\n }\n //_ruleObj = JSON.parse(regex.split(/::/).splice(1)[0].replace(/([^\\W+ true false])+(\\w+)/g, '\"$&\"')); \n if (typeof(_ruleObj.query) != 'undefined' && typeof(_ruleObj.query.data) != 'undefined') {\n // since we only have one param\n // :var1 == :var1\n if ( urlVar == _ruleObj.query.data[ Object.keys(_ruleObj.query.data)[0] ] ) {\n _ruleObj.query.data[ Object.keys(_ruleObj.query.data)[0] ] = _data[key];\n // Set in case it is not found\n request.params[key] = _data[key];\n }\n }\n _rule[key] = _ruleObj; \n _validator = new Validator('routing', _data, null, _rule );\n if (_ruleObj.count() == 0 ) {\n console.error('Route validation failed '+ params.rule);\n return false;\n }\n for (let rule in _ruleObj) {\n if (Array.isArray(_ruleObj[rule])) { // has args\n await _validator[key][rule].apply(_validator[key], _ruleObj[rule]);\n } else {\n await _validator[key][rule](_ruleObj[rule], request, response, next);\n } \n }\n tested = _validator.isValid();\n } else {\n tested = new RegExp(params.requirements[key]).test(urlVal);\n }\n\n if (\n typeof(params.param[key]) != 'undefined' &&\n typeof(params.requirements) != 'undefined' &&\n typeof(params.requirements[key]) != 'undefined' &&\n typeof(request.params) != 'undefined' &&\n tested\n ) { \n request.params[key] = urlVal;\n if ( typeof(request[requestMethod][key]) == 'undefined' ) {\n request[requestMethod][key] = urlVal;\n }\n return true;\n }\n\n } else { // slow one\n\n // In order to support rules defined like :\n // { params.url } => `/section/:name/page:number`\n // { request.url } => `/section/plante/page4`\n //\n // with keys = [ \":name\", \":number\" ]\n\n var keys = _param\n , tplUrl = params.url\n , url = request.url\n , values = {}\n , strVal = ''\n , started = false\n , i = 0\n ;\n\n for (var c = 0, posLen = url.length; c < posLen; ++c) {\n if (url.charAt(c) == tplUrl.charAt(i) && !started) {\n ++i\n continue\n } else if (strVal == '') { // start\n\n started = true;\n strVal += url.charAt(c);\n } else if (c > (tplUrl.indexOf(keys[0]) + keys[0].length)) {\n\n regex = params.requirements[keys[0]];\n urlVal = strVal.substr(0, strVal.length);\n\n if (/^\\//.test(regex)) {\n re = regex.match(/\\/(.*)\\//).pop();\n flags = regex.replace('/' + re + '/', '');\n\n tested = new RegExp(re, flags).test(urlVal)\n\n } else if ( /^validator\\:\\:/.test(regex) ) {\n /**\n * \"requirements\" : {\n * \"id\" : \"/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\",\n * \"email\": \"validator::{ isEmail: true, isString: [7] }\"\n * }\n * \n * e.g.: tested = new Validator('routing', _data, null, {email: {isEmail: true}} ).isEmail().valid;\n */ \n _data = {}; _ruleObj = {}; _rule = {}; str = ''; \n urlVar.replace( new RegExp('[^'+ key[0] +']','g'), function(){ str += arguments[0] }); \n _data[key[0]] = urlVal.replace( new RegExp(str, 'g'), '');\n _ruleObj = JSON.parse(regex.split(/::/).splice(1)[0].replace(/([^\\W+ true false])+(\\w+)/g, '\"$&\"')); \n _rule[key[0]] = _ruleObj; \n _validator = new Validator('routing', _data, null, _rule );\n \n for (let rule in _ruleObj) {\n if (Array.isArray(_ruleObj[rule])) { // has args\n _validator[key[0]][rule].apply(_validator[key[0]], _ruleObj[rule])\n } else {\n _validator[key[0]][rule](_ruleObj[rule])\n } \n }\n tested = _validator.isValid();\n } else {\n tested = new RegExp(params.requirements[key[0]]).test(urlVal)\n }\n\n if (tested) {\n values[keys[0].substr(1)] = urlVal\n } else {\n return false\n }\n\n strVal = '';\n started = false;\n i = (tplUrl.indexOf(keys[0]) + keys[0].length);\n c -= 1;\n\n keys.splice(0, 1)\n } else {\n strVal += url.charAt(c);\n ++i\n }\n\n if (c == posLen - 1) {\n\n regex = params.requirements[keys[0]];\n urlVal = strVal.substr(0, strVal.length);\n\n if (/^\\//.test(regex)) {\n re = regex.match(/\\/(.*)\\//).pop();\n flags = regex.replace('/' + re + '/', '');\n\n tested = new RegExp(re, flags).test(urlVal)\n\n } else {\n tested = new RegExp(params.requirements[key]).test(urlVal)\n }\n\n if (tested) {\n values[keys[0].substr(1)] = urlVal\n } else {\n return false\n }\n }\n }\n\n if (values.count() == keys.length) {\n key = null;\n for (key in values) {\n request.params[key] = values[key];\n }\n return true\n }\n }\n\n return false\n }\n \n var replacement = function(matched){\n return ( /\\/$/.test(matched) ? replacement.variable+ '/': replacement.variable ) \n };\n var checkRouteParams = function(route, params) {\n var variable = null\n , regex = null\n , urls = null\n , i = null\n , len = null\n , rawRouteUrl = route.url\n , p = null\n , pLen = null\n ;\n for (p in route.param) {\n if ( typeof(params) != 'undefined' && typeof(params[p]) == 'undefined' ) continue;\n \n if ( /^:/.test(route.param[p]) ) {\n variable = route.param[p].substr(1);\n \n if ( typeof(params) != 'undefined' && typeof(params[variable]) != 'undefined' ) {\n \n regex = new RegExp('(:'+variable+'/|:'+variable+'$)', 'g'); \n \n\n if ( typeof(route.param.path) != 'undefined' && /:/.test(route.param.path) ) {\n route.param.path = route.param.path.replace( regex, params[variable]);\n }\n if (typeof (route.param.title) != 'undefined' && /:/.test(route.param.title)) {\n route.param.title = route.param.title.replace( regex, params[variable]);\n }\n if (typeof (route.param.namespace) != 'undefined' && /:/.test(route.param.namespace)) {\n route.param.namespace = route.param.namespace.replace( regex, params[variable]);\n }\n // file is handle like url replacement (path is like pathname)\n if (typeof (route.param.file) != 'undefined' && /:/.test(route.param.file)) {\n replacement.variable = params[variable]; \n route.param.file = route.param.file.replace( regex, replacement );\n }\n \n if ( /\\,/.test(route.url) ) { \n urls = route.url.split(/\\,/g);\n i = 0; len = urls.length;\n for (; i < len; ++i) {\n replacement.variable = params[variable]; \n urls[i] = urls[i].replace( regex, replacement );\n }\n route.url = urls.join(',');\n } else { \n replacement.variable = params[variable]; \n route.url = route.url.replace( regex, replacement );\n }\n }\n }\n }\n \n // Selecting url in case of multiple urls & optional requirmements\n if ( urls ) { \n i = 0; len = urls.length;\n var rawUrlVars = null\n , rawUrlScore = null\n , rawUrls = rawRouteUrl.split(/\\,/g)\n , pKey = null\n , lastScore = 0\n ;\n route.urlIndex = 0; // by default\n for (; i < len; ++i) {\n rawUrlScore = 0;\n rawUrlVars = rawUrls[0].match(/\\:[-_a-z0-9]+/ig);\n if ( !rawUrlVars ) continue;\n p = 0;\n pLen = rawUrlVars.length;\n for (; p < pLen; p++) {\n pKey = rawUrlVars[p].substr(1);\n if ( typeof(params[ pKey ]) != 'undefined' && params[ pKey ] ) {\n rawUrlScore++;\n }\n }\n // We just rely in params count for now\n if (rawUrlScore > lastScore) {\n lastScore = rawUrlScore;\n route.urlIndex = i;\n }\n }\n } \n \n return route;\n }\n\n /**\n * @function getRoute\n *\n * @param {string} rule e.g.: [ <scheme>:// ]<name>[ @<bundle> ][ /<environment> ]\n * @param {object} params\n * @param {number} [urlIndex] in case you have more than one url registered for the current route, you can select the one you want to use. Default is 0.\n *\n * @returns {object} route\n * */\n self.getRoute = function(rule, params, urlIndex) {\n \n var config = null;\n if (isGFFCtx) {\n config = window.gina.config;\n } else {\n config = getContext('gina').config;\n if ( typeof(getContext('argvFilename')) != 'undefined' ) {\n config.getRouting = getContext('gina').Config.instance.getRouting;\n }\n }\n \n var env = config.env || GINA_ENV // by default, takes the current bundle\n , envTmp = null\n //, scheme = null\n , bundle = config.bundle // by default, takes the current bundle\n ;\n \n if ( !/\\@/.test(rule) && typeof(bundle) != 'undefined' && bundle != null) {\n rule = rule.toLowerCase()\n rule += '@' + bundle\n }\n\n if ( /\\@/.test(rule) ) {\n\n var arr = ( rule.replace(/(.*)\\:\\/\\//, '') ).split(/\\@/);\n\n bundle = arr[1];\n\n // getting env\n if ( /\\/(.*)$/.test(rule) ) {\n envTmp = ( rule.replace(/(.*)\\:\\/\\//, '') ).split(/\\/(.*)$/)[1];\n bundle = bundle.replace(/\\/(.*)$/, '');\n env = envTmp || env;\n }\n\n\n // getting scheme\n //scheme = ( /\\:\\/\\//.test(rule) ) ? rule.split(/\\:\\/\\//)[0] : config.bundlesConfiguration.conf[bundle][env].server.scheme;\n\n rule = arr[0].toLowerCase() +'@'+ bundle;\n }\n \n \n var routing = config.getRouting(bundle, env);\n\n if ( typeof(routing[rule]) == 'undefined' ) {\n throw new Error('[ RoutingHelper::getRouting(rule, params) ] : `' +rule + '` not found !')\n }\n\n var route = JSON.clone(routing[rule]);\n var variable = null\n , regex = null\n , urls = null\n , i = null\n , len = null\n , msg = null\n ;\n route = checkRouteParams(route, params);\n\n if ( /\\,/.test(route.url) ) {\n if ( typeof(route.urlIndex) != 'undefined' ) {\n urlIndex = route.urlIndex; // set by checkRouteParams(route, params)\n delete route.urlIndex;\n }\n urlIndex = ( typeof(urlIndex) != 'undefined' ) ? urlIndex : 0;\n route.url = route.url.split(/,/g)[urlIndex]; \n }\n // fix url in case of empty param value allowed by the routing rule\n // to prevent having a folder.\n // eg.: {..., id: '/^\\\\s*$/'} => {..., id: ''} => /path/to/ becoming /path/to\n if ( /\\/$/.test(route.url) && route.url != '/' )\n route.url = route.url.substr(0, route.url.length-1);\n \n // Completeting url with extra params e.g.: ?param1=val1¶m2=val2\n if ( /GET/i.test(route.method) && typeof(params) != 'undefined' ) {\n var queryParams = '?', maskedUrl = routing[rule].url;\n //self.reservedParams;\n for (let r in route.param) {\n if ( self.reservedParams.indexOf(r) > -1 || new RegExp(route.param[r]).test(maskedUrl) )\n continue;\n if (typeof(params[r]) != 'undefined' )\n queryParams += r +'='+ encodeURIComponent(params[r])+ '&';\n }\n \n if (queryParams.length > 1) {\n queryParams = queryParams.substring(0, queryParams.length-1);\n route.url += queryParams;\n }\n }\n \n // recommanded for x-bundle coms\n // leave `ignoreWebRoot` empty or set it to false for x-bundle coms\n route.toUrl = function (ignoreWebRoot) {\n \n var urlProps = null;\n if ( /^redirect$/i.test(this.param.control) ) {\n urlProps = self.getUrlProps(this.bundle, (env||GINA_ENV));\n }\n \n var wroot = this.webroot || urlProps.webroot\n , hostname = this.hostname || urlProps.hostname\n , path = this.url\n ;\n \n this.url = ( typeof(ignoreWebRoot) != 'undefined' && ignoreWebRoot == true ) ? path.replace(wroot, '/') : path;\n\n return hostname + this.url\n };\n \n /**\n * request current url\n * \n * \n * \n * @param {boolean} [ignoreWebRoot]\n * @param {object} [options] - see: https://nodejs.org/api/https.html#https_new_agent_options\n * @param {object} [_this] - current context: only used when `promisify`is used\n * \n * @callback {callback} [cb] - see: https://nodejs.org/api/https.html#https_new_agent_options\n * @param {object} res\n */\n route.request = function(ignoreWebRoot, options) {\n \n var cb = null, _this = null;\n if ( typeof(arguments[arguments.length-1]) == 'function' ) {\n cb = arguments[arguments.length-1];\n }\n if ( typeof(arguments[2]) == 'object' ) {\n _this = arguments[2];\n }\n \n var wroot = this.webroot || _this.webroot\n , hostname = this.hostname || _this.hostname\n , url = ( typeof(ignoreWebRoot) != 'undefined' && ignoreWebRoot == true ) ? path.replace(wroot, '/') : this.url || _this.url\n ;\n \n var scheme = ( /^https/.test(hostname) ) ? 'https' : 'http';\n \n if (isGFFCtx) {\n var target = ( typeof(options) != 'undefined' && typeof(options.target) != 'undefined' ) ? options.target : \"_self\";\n window.open(url, target)\n } else {\n if ( typeof(options.agent) == 'undefined' ) {\n // See.: https://nodejs.org/api/http.html#http_class_http_agent\n // create an agent just for this request\n options.agent = false;\n }\n var agent = require(''+scheme); \n var onAgentResponse = function(res) { \n \n var data = '', err = false;\n \n res.on('data', function (chunk) {\n data += chunk;\n });\n res.on('error', function (error) {\n err = 'Failed to get mail content';\n if (error && typeof(error.stack) != 'undefined' ) {\n err += error.stack;\n } else if ( typeof(error) == 'string' ) {\n err += '\\n' + error;\n }\n });\n res.on('end', function () {\n if (/^\\{/.test(data) ) {\n try {\n data = JSON.parse(data);\n if (typeof(data.error) != 'undefined') {\n err = JSON.clone(data);\n data = null;\n }\n } catch(parseError) {\n err = parseError\n }\n }\n if (err) { \n cb(err);\n return;\n }\n \n cb(false, data);\n return;\n });\n }\n if (cb) { \n agent.get(url, options, onAgentResponse);\n } else {\n // just throw the request without waiting/handling response\n agent.get(url, options);\n } \n }\n return; \n \n } // EO route.request()\n \n if ( /\\:/.test(route.url) ) {\n var paramList = route.url\n .match(/(\\:(.*)\\/|\\:(.*)$)/g)\n .map(function(el){ return el.replace(/\\//g, ''); }).join(', ');\n msg = '[ RoutingHelper::getRoute(rule[, bundle, method]) ] : route [ %r ] param placeholder not defined: `' + route.url + '` !\\n Check your route description to compare requirements against param variables [ '+ paramList +']';\n msg = msg.replace(/\\%r/, rule);\n var err = new Error(msg);\n console.warn( err );\n // Do not throw error nor return here !!!\n }\n\n return route\n };\n\n var getFormatedRoute = function(route, url, hash) {\n // fix url in case of empty param value allowed by the routing rule\n // to prevent having a folder.\n // eg.: {..., id: '/^\\\\s*$/'} => {..., id: ''} => /path/to/ becoming /path/to\n if ( /\\/$/.test(url) && url != '/' )\n url = url.substr(0, url.length-1);\n // adding hash if found\n if (hash)\n url += hash;\n \n route.url = url;\n // recommanded for x-bundle coms\n // leave `ignoreWebRoot` empty or set it to false for x-bundle coms\n route.toUrl = function (ignoreWebRoot) { \n var wroot = this.webroot\n , hostname = this.hostname\n , path = this.url\n ;\n \n this.url = ( typeof(ignoreWebRoot) != 'undefined' && ignoreWebRoot == true ) ? path.replace(wroot, '/') : path;\n\n return hostname + this.url\n };\n \n return route\n }\n\n /**\n * Get route by url\n * N.B.: this will only work with rules declared with `GET` method property\n *\n * @function getRouteByUrl\n *\n * @param {string} url e.g.: /webroot/some/url/path or http\n * @param {string} [bundle] targeted bundle\n * @param {string} [method] request method (GET|PUT|PUT|DELETE) - GET is set by default\n * @param {object} [request] \n * @param {boolean} [isOverridinMethod] // will replace request.method by the provided method - Used for redirections\n * \n * @returns {object|boolean} route - when route is found; `false` when not found\n * */\n \n self.getRouteByUrl = function (url, bundle, method, request, isOverridinMethod) {\n \n if (\n arguments.length == 2 \n && typeof(arguments[1]) != 'undefined' \n && self.allowedMethods.indexOf(arguments[1].toLowerCase()) > -1 \n ) {\n method = arguments[1];\n bundle = undefined;\n }\n var webroot = null\n , route = null\n , routing = null\n , reverseRouting = null\n , hash = null // #section nav\n , hostname = null\n , host = null\n ;\n \n if ( /\\#/.test(url) && url.length > 1 ) {\n var urlPart = url.split(/\\#/);\n url = urlPart[0];\n hash = '#' + urlPart[1];\n \n urlPart = null;\n }\n \n // fast method\n if (\n arguments.length == 1 \n && typeof(arguments[0]) != 'undefined' \n ) {\n if ( !/^(https|http)/i.test(url) && !/^\\//.test(url)) {\n url = '/'+ url;\n }\n \n webroot = '/' + url.split(/\\//g)[1];\n if (isGFFCtx) {\n reverseRouting = gina.config.reverseRouting;\n routing = gina.config.routing\n }\n // get bundle\n if ( typeof(reverseRouting[webroot]) != 'undefined' ) {\n var infos = routing[ reverseRouting[webroot] ];\n bundle = infos.bundle;\n webroot = infos.webroot;\n host = infos.host;\n hostname = infos.hostname;\n infos = null;\n } \n }\n \n isOverridinMethod = ( typeof(arguments[arguments.length-1]) != 'boolean') ? false : arguments[arguments.length-1];\n\n var matched = false \n , config = null\n , env = null\n , prefix = null\n , pathname = null\n , params = null\n , isRoute = null\n , foundRoute = null \n , routeObj = null \n ;\n \n \n \n var isMethodProvidedByDefault = ( typeof(method) != 'undefined' ) ? true : false;\n\n if (isGFFCtx) {\n config = window.gina.config;\n bundle = (typeof (bundle) != 'undefined') ? bundle : config.bundle;\n env = config.env;\n routing = routing || config.getRouting(bundle);\n reverseRouting = reverseRouting || config.reverseRouting;\n isXMLRequest = ( typeof(isXMLRequest) != 'undefined' ) ? isXMLRequest : false; // TODO - retrieve the right value\n\n hostname = hostname || config.hostname;\n webroot = webroot || config.webroot;\n prefix = hostname + webroot;\n\n request = {\n routing: {},\n method: method,\n params: {},\n url: url\n };\n } else {\n\n var gnaCtx = getContext('gina');\n \n config = gnaCtx.config;\n bundle = (typeof (bundle) != 'undefined') ? bundle : config.bundle;\n env = config.env;\n routing = config.getRouting(bundle);\n \n \n\n hostname = config.envConf[bundle][env].hostname;\n webroot = config.envConf[bundle][env].server.webroot;\n prefix = hostname + webroot;\n \n if ( !request ) {\n request = {\n routing: {},\n isXMLRequest: false,\n method : ( typeof(method) != 'undefined' ) ? method.toLowerCase() : 'get',\n params: {},\n url: url\n }\n }\n if (isOverridinMethod) {\n request.method = method;\n }\n isXMLRequest = request.isXMLRequest || false;\n }\n\n pathname = url.replace( new RegExp('^('+ hostname +'|'+hostname.replace(/\\:\\d+/, '') +')' ), '');\n if ( typeof(request.routing.path) == 'undefined' )\n request.routing.path = unescape(pathname);\n method = ( typeof(method) != 'undefined' ) ? method.toLowerCase() : 'get';\n \n if (isMethodProvidedByDefault) {\n // to handle 303 redirect like PUT -> GET\n request.originalMethod = request.method;\n \n request.method = method;\n request.routing.path = unescape(pathname)\n }\n // last method check\n if ( !request.method)\n request.method = method;\n\n // getting params\n params = {};\n \n \n\n var paramsList = null;\n var re = new RegExp(method, 'i');\n var localMethod = null;\n // N.B.: this part of the code must remain identical to the one used in `server.js`\n out:\n for (var name in routing) {\n if (typeof (routing[name]['param']) == 'undefined')\n break;\n\n // bundle filter\n if (routing[name].bundle != bundle) continue;\n\n // method filter\n localMethod = routing[name].method; \n if ( /\\,/.test( localMethod ) && re.test(localMethod) ) {\n localMethod = request.method\n } \n if (typeof (routing[name].method) != 'undefined' && !re.test(localMethod)) continue;\n \n //Preparing params to relay to the core/router. \n params = {\n method : localMethod,\n requirements : routing[name].requirements,\n namespace : routing[name].namespace || undefined,\n url : unescape(pathname), /// avoid %20\n rule : routing[name].originalRule || name,\n param : routing[name].param,\n //middleware: routing[name].middleware,\n middleware : JSON.clone(routing[name].middleware),\n bundle : routing[name].bundle,\n isXMLRequest : isXMLRequest\n };\n\n // normal case\n //Parsing for the right url.\n try { \n \n isRoute = self.compareUrls(params, routing[name].url, request);\n\n if (isRoute.past) {\n\n route = JSON.clone(routing[name]);\n route.name = name;\n\n matched = true;\n isRoute = {};\n\n break;\n }\n\n } catch (err) {\n throw new Error('Route [ ' + name + ' ] needs your attention.\\n' + err.stack);\n }\n } //EO for break out\n\n if (!matched) {\n if (isGFFCtx) { \n var urlHasChanged = false; \n if ( \n url == '#' \n && /GET/i.test(method) \n && isMethodProvidedByDefault \n || /^404\\:/.test(url)\n ) {\n url = location.pathname;\n urlHasChanged = true;\n }\n \n if ( typeof(self.notFound) == 'undefined' ) {\n self.notFound = {}\n }\n \n var notFound = null, msg = '[ RoutingHelper::getRouteByUrl(rule[, bundle, method]) ] : route [ %r ] is called but not found inside your view: `' + url + '` !';\n if ( gina.hasPopinHandler && gina.popinIsBinded ) {\n notFound = gina.popin.getActivePopin().target.innerHTML.match(/404\\:\\[\\w+\\][a-z 0-9-_@]+/);\n } else {\n notFound = document.body.innerHTML.match(/404\\:\\[\\w+\\][a-z 0-9-_@]+/);\n }\n \n notFound = (notFound && notFound.length > 0) ? notFound[0] : null;\n \n if ( notFound && isMethodProvidedByDefault && urlHasChanged ) {\n \n var m = notFound.match(/\\[\\w+\\]/)[0]; \n \n notFound = notFound.replace('404:'+m, m.replace(/\\[|\\]/g, '')+'::' );\n \n msg = msg.replace(/\\%r/, notFound.replace(/404\\:\\s+/, ''));\n \n if (typeof(self.notFound[notFound]) == 'undefined') {\n self.notFound[notFound] = { \n count: 1,\n message: msg \n };\n } else if ( isMethodProvidedByDefault && typeof(self.notFound[notFound]) != 'undefined' ) {\n ++self.notFound[notFound].count;\n }\n \n return false \n } \n \n notFound = null; \n \n var altRule = gina.config.reverseRouting[url] || null; \n if (\n !notFound \n && altRule\n && typeof(altRule) != 'undefined'\n && altRule.split(/\\@(.+)$/)[1] == bundle\n ) {\n \n notFound = altRule;\n if ( typeof(self.notFound[notFound]) == 'undefined' ) {\n \n msg = msg.replace(/\\%r/, method.toUpperCase() +'::'+ altRule);\n \n self.notFound[notFound] = { \n count: 1,\n message: msg \n };\n //console.warn(msg); \n } else if ( isMethodProvidedByDefault && typeof(self.notFound[notFound]) != 'undefined' ) {\n ++self.notFound[notFound].count;\n }\n \n return false\n }\n \n // forms\n var altRoute = self.compareUrls(params, url, request) || null;\n if(altRoute.past && isMethodProvidedByDefault) {\n notFound = method.toUpperCase() +'::'+ altRoute.request.routing.rule;\n if ( typeof(self.notFound[notFound]) == 'undefined' ) {\n msg = msg.replace(/\\%r/, notFound);\n //console.warn(msg); \n } else {\n ++self.notFound[notFound].count;\n }\n \n return false\n } \n return false\n }\n\n \n console.warn( new Error('[ RoutingHelper::getRouteByUrl(rule[, bundle, method, request]) ] : route not found for url: `' + url + '` !').stack ); \n return false;\n } else {\n // fix url in case of empty param value allowed by the routing rule\n // to prevent having a folder.\n // eg.: {..., id: '/^\\\\s*$/'} => {..., id: ''} => /path/to/ becoming /path/to\n if ( /\\/$/.test(url) && url != '/' )\n url = url.substr(0, url.length-1);\n // adding hash if found\n if (hash)\n url += hash;\n \n route.url = url;\n // recommanded for x-bundle coms\n // leave `ignoreWebRoot` empty or set it to false for x-bundle coms\n route.toUrl = function (ignoreWebRoot) { \n var wroot = this.webroot\n , hostname = this.hostname\n , path = this.url\n ;\n \n this.url = ( typeof(ignoreWebRoot) != 'undefined' && ignoreWebRoot == true ) ? path.replace(wroot, '/') : path;\n \n return hostname + this.url\n };\n \n return route\n }\n }\n\n return self\n}\n\nif ((typeof (module) !== 'undefined') && module.exports) {\n // Publish as node.js module\n module.exports = Routing()\n} else if (typeof (define) === 'function' && define.amd) {\n // Publish as AMD module \n define('utils/routing', ['require', 'utils/form-validator', 'utils/merge'], function() { return Routing() })\n};\n",
|
|
42
|
-
"/**\n * Gina Local Storage\n * N.B.: this is based on Web StorageAPI & Node LocalStorage\n * See.:\n * - https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API\n * - https://www.npmjs.com/package/node-localstorage\n * */\nfunction StoragePlugin(options) {\n\n var merge = merge || require('utils/merge');;\n var Collection = Collection || require('utils/collection');\n var uuid = uuid || require('vendor/uuid');\n var dateFormat = dateFormat || require('helpers/dateFormat');\n\n\n var self = {\n 'options' : {\n 'bucket': 'default'\n }\n };\n\n var bucketInstance = {};\n var storage = null;\n\n var entities = {}, collections = {}; // entities & collections (data) objects\n var keywords = ['not null']; // TODO - null, exists\n\n\n var proto = {\n 'bucket' : undefined,\n 'drop' : bucketDrop,\n 'Collection': Collection\n };\n\n var entityProto = {\n 'insert' : collectionInsert,\n 'find' : collectionFind,\n 'findOne' : collectionFindOne,\n 'update' : null,\n 'delete' : collectionDelete,\n 'drop' : collectionDrop\n };\n\n var init = function(options) {\n\n // detect if cookies are enabled\n if ( !window.localStorage || window.localStorage && ! typeof(window.localStorage.setItem) == 'undefined' ) {\n throw new Error('Make sure your browser supports `window.localStorage` to use Gina Storage. See: `https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API#Browser_compatibility`');\n }\n\n if ( typeof(options) != 'object' && typeof(options) != 'undefined' ) {\n throw new Error('`options` must be an object')\n } else if ( typeof(options) == 'undefined' ) {\n var options = {}\n }\n\n self.options = merge(options, self.options);\n storage = window.localStorage;\n\n var bucketName = self.options['bucket'];\n var bucket = storage.getItem(bucketName);\n\n if (!bucket && bucketName != undefined) {\n //console.log('creating new bucket !');\n bucketCreate(bucketName);\n } else if (bucketName == undefined) {\n throw new Error('`bucket` name cannot be undefined')\n }\n\n bucketInstance['bucket'] = bucketName;\n bucketInstance = merge(bucketInstance, proto);\n }\n\n\n\n /**\n * Create bucket\n *\n * @param {string} bucketName\n * */\n var bucketCreate = function(bucketName) {\n storage.setItem(bucketName, JSON.stringify(collections));\n }\n\n\n /**\n * Drop bucket\n *\n * */\n function bucketDrop() {\n storage.removeItem(self.options['bucket']);\n bucketInstance = null;\n\n for (var prop in this) {\n delete this[prop]\n }\n\n return bucketInstance;\n }\n\n var collectionSave = function (enforceDeleted) {\n\n var enforceDeleted = enforceDeleted || false;\n\n try {\n //backing up collections\n var tmpCollections = JSON.clone(collections);\n var index = this['_index'];\n var collection = this['_collection'];\n var bucket = this['_bucket'];\n var filter = this['_filter'];\n this['_updatedAt'] = new Date().format(\"isoDateTime\");\n\n merge(tmpCollections[ collection ][ index ], this, true);\n\n // cleaning\n delete tmpCollections[ collection ][ index ]['_index'];\n delete tmpCollections[ collection ][ index ]['_collection'];\n delete tmpCollections[ collection ][ index ]['_bucket'];\n delete tmpCollections[ collection ][ index ]['save'];\n delete tmpCollections[ collection ][ index ]['_filter'];\n\n if (enforceDeleted && typeof(tmpCollections[ collection ][ index ]) == 'object' ) {\n\n var parseEnforcedCollection = function (arr, target) {\n for (var i = 0, len = arr.length; i < len; ++i) {\n if ( typeof (target[i]) == 'object' && typeof(arr[i]) != 'undefined' && !Array.isArray(arr[i]) ) {\n parseEnforced(arr[i], target[i])\n } else if ( !Array.isArray(arr[i]) ){\n if (typeof(arr[i]) == 'undefined') {\n delete target[i]\n }\n } else { // is collection type\n parseEnforcedCollection(arr[i], target[i])\n }\n }\n\n return target\n }\n\n var parseEnforced = function (obj, target) {\n for (var prop in target) {\n if ( typeof (target[prop]) == 'object' && typeof(obj[prop]) != 'undefined' && !Array.isArray(obj[prop]) ) {\n parseEnforced(obj[prop], target[prop])\n } else if ( !Array.isArray(obj[prop]) ){\n if (typeof(obj[prop]) == 'undefined') {\n delete target[ prop ]\n }\n } else { // is collection type\n parseEnforcedCollection(obj[prop], target[prop])\n }\n }\n\n return target\n };\n\n if ( Array.isArray(tmpCollections[ collection ][ index ]) ) {\n tmpCollections[ collection ][ index ] = parseEnforcedCollection(this, tmpCollections[ collection ][ index ])\n } else if ( typeof(tmpCollections[ collection ][ index ] ) == 'object' ) {\n tmpCollections[ collection ][ index ] = parseEnforced(this, tmpCollections[ collection ][ index ])\n } else {\n if (typeof(this[prop]) == 'undefined') {\n delete tmpCollections[ collection ][ index ]\n }\n }\n }\n\n collections[ collection ][ index ] = tmpCollections[ collection ][ index ];\n\n // saving\n storage.setItem(bucket, JSON.stringify(collections));\n\n return collectionFindOne(filter)\n\n } catch (err) {\n throw err\n }\n }\n\n /**\n * Create or Get Collection by name\n *\n * @param {string} name - Collection name\n * */\n function Collection(name) {\n // retrieve collections state\n collections = JSON.parse(storage.getItem(this['bucket']));\n //console.log('collections ', (collections || null) );\n if ( typeof(collections[name]) == 'undefined' ) {\n collections[name] = [];\n storage.setItem(this['bucket'], JSON.stringify(collections));\n collections = JSON.parse(storage.getItem(this['bucket']));\n }\n\n entities[name] = { '_collection': name, '_bucket': this['bucket'] };\n entities[name] = merge(entities[name], entityProto);\n\n return entities[name]\n }\n\n /**\n * Drop collection\n *\n * @param {string} name\n * */\n function collectionDrop(name) {\n if ( typeof(collections[ this['_collection'] ]) == 'undefined' ) {\n throw new Error('Collection `'+name+'` not found')\n }\n\n delete entities[ this['_collection'] ]; // delete entity\n delete collections[ this['_collection'] ]; // delete data\n\n storage.setItem(this['_bucket'], JSON.stringify(collections));\n }\n\n\n /**\n * Insert into collection\n *\n * @param {object} content\n * */\n function collectionInsert(content) {\n\n // TODO - add uuid\n content['_id'] = uuid.v1();\n content['_createdAt'] = new Date().format(\"isoDateTime\");\n content['_updatedAt'] = new Date().format(\"isoDateTime\");\n\n collections[ this['_collection'] ][ collections[ this['_collection'] ].length ] = content;\n\n storage.setItem(this['_bucket'], JSON.stringify(collections));\n }\n\n /**\n * Find from collection\n *\n * // TODO - add options\n *\n * @param {object} filter\n * @param {object} [options] - e.g.: limit\n *\n * @returns {array} result\n * */\n function collectionFind(filter, options) {\n if (!filter) {\n // TODO - limit of ten by\n return collections[ this['_collection'] ]\n }\n\n if ( typeof(filter) !== 'object' ) { // == findAll\n throw new Error('filter must be an object');\n } else {\n //console.log('search into ', this['_collection'], collections[ this['_collection'] ], collections);\n var content = collections[ this['_collection'] ]\n , condition = filter.count()\n , i = 0\n , found = []\n , localeLowerCase = '';\n\n for (var o in content) {\n for (var f in filter) {\n localeLowerCase = ( typeof(filter[f]) != 'boolean' ) ? filter[f].toLocaleLowerCase() : filter[f];\n if ( filter[f] && keywords.indexOf(localeLowerCase) > -1 && localeLowerCase == 'not null' && typeof(content[o][f]) != 'undefined' && typeof(content[o][f]) !== 'object' && content[o][f] != 'null' && content[o][f] != 'undefined' ) {\n if (found.indexOf(content[o][f]) < 0 ) {\n found[i] = content[o][f];\n ++i\n }\n\n } else if ( typeof(content[o][f]) != 'undefined' && typeof(content[o][f]) !== 'object' && content[o][f] === filter[f] ) {\n found[i] = content[o];\n ++i\n }\n }\n }\n }\n\n return found\n }\n\n //function collectionLimit(limit) {}\n\n /**\n * Find a single result from collection\n *\n * e.g:\n * // getting a record\n * > var objectRecord = <bucket>.Collection('myBucket').findOne({_name: \"someName\"});\n *\n * // updating record by adding or updating an existing property\n * > objectRecord.myProperty = 'some value';\n * > objectRecord.save();\n *\n * // deleting record\n * > objectRecord.myProperty.delete()\n *\n * @param {object} filter\n *\n * @returns {object|array|string} result\n *\n * */\n function collectionFindOne(filter) {\n\n if ( typeof(filter) !== 'object' ) {\n throw new Error('filter must be an object');\n } else {\n var content = collections[ this['_collection'] ]\n , condition = filter.count()\n , i = 0\n , result = null\n , localeLowerCase = '';\n\n\n //console.log('condition ', condition, '\\nfitler', filter, '\\ncontent', content);\n if (condition == 0) return null;\n\n for (var o in content) {\n for (var f in filter) {\n localeLowerCase = ( typeof(filter[f]) != 'boolean' ) ? filter[f].toLocaleLowerCase() : filter[f];\n if ( filter[f] && keywords.indexOf(localeLowerCase) > -1 && localeLowerCase == 'not null' && typeof(content[o][f]) != 'undefined' && typeof(content[o][f]) !== 'object' && content[o][f] === filter[f] && content[o][f] != 'null' && content[o][f] != 'undefined' ) {\n if (result.indexOf(content[o][f]) < 0 ) {\n ++i;\n if (i === condition) {\n result = content[o];\n result['_index'] = o;\n result['_collection'] = this['_collection'];\n result['_bucket'] = this['_bucket'];\n }\n\n }\n\n } else if ( typeof(content[o][f]) != 'undefined' && typeof(content[o][f]) !== 'object' && content[o][f] === filter[f] ) {\n ++i;\n if (i === condition) {\n result = content[o];\n result['_index'] = o;\n result['_collection'] = this['_collection'];\n result['_bucket'] = this['_bucket'];\n result['_filter'] = filter;\n }\n }\n }\n }\n }\n\n if (result) {\n /**\n * save\n * e.g.:\n * // updating property\n * <obj>.property = 'value';\n * <obj>.save();\n *\n * // deleting property\n * delete <obj>.property;\n * <obj>.save(true);\n *\n * @param {boolean} enforceDeleted\n * */\n result['save'] = collectionSave\n }\n\n\n return result\n }\n\n /**\n * Delete from collection\n *\n * @param {object} filter\n *\n * @returns {array} result\n * */\n function collectionDelete(filter) {\n\n if ( typeof(filter) !== 'object' ) {\n throw new Error('filter must be an object');\n } else {\n var content = JSON.clone( collections[ this['_collection'] ] )\n //, condition = filter.count()\n , i = 0\n , found = [];\n\n for (var o in content) {\n for (var f in filter) {\n if ( filter[f] && keywords.indexOf(filter[f].toLocaleLowerCase()) > -1 && filter[f].toLowerCase() == 'not null' && typeof(content[o][f]) != 'undefined' && typeof(content[o][f]) !== 'object' && content[o][f] != 'null' && content[o][f] != 'undefined' ) {\n if (found.indexOf(content[o][f]) < 0 ) {\n found[i] = content[o][f];\n delete collections[ this['_collection'] ][o][f];\n ++i\n }\n\n } else if ( typeof(content[o][f]) != 'undefined' && typeof(content[o][f]) !== 'object' && content[o][f] === filter[f] ) {\n found[i] = content[o];\n collections[ this['_collection'] ].splice(o, 1);\n ++i\n }\n }\n }\n }\n\n if (found.length > 0 ) {\n storage.setItem(this['_bucket'], JSON.stringify(collections));\n return true\n }\n\n return false\n }\n\n init(options);\n\n\n return bucketInstance\n};\n\nif ( ( typeof(module) !== 'undefined' ) && module.exports ) {\n // Publish as node.js module\n var merge = require('utils/merge'); //require('../../../../../lib/merge');\n var Collection = require('utils/collection'); //require('../../../../../lib/collection');\n var uuid = require('uuid');\n\n module.exports = StoragePlugin\n\n} else if ( typeof(define) === 'function' && define.amd) {\n // Publish as AMD module\n define('gina/storage', ['helpers/dateFormat', 'helpers/prototypes'],function() { return StoragePlugin })\n};\n",
|
|
43
|
-
"/**\n * Operations on selectors\n * */\n\nfunction insertAfter(referenceNode, newNode) {\n referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling)\n}\n\nfunction getElementsByAttribute(attribute) {\n var matching = [], m = 0;\n var els = document.getElementsByTagName('*');\n\n for (var i = 0, n = els.length; i < n; ++i) {\n if (els[i].getAttribute(attribute) !== null) {\n // Element exists with attribute. Add to array.\n matching[m] = els[i];\n ++m\n }\n }\n\n return matching\n}\n\n/*\n * DOMParser HTML extension\n * 2012-09-04\n * \n * By Eli Grey, http://eligrey.com\n * Public domain.\n * \n * Added in gina on: 2020-12-12\n * \n */\n\n/*! @source https://gist.github.com/1129031 */\n/*global document, DOMParser*/\n(function(DOMParser) {\n\t\"use strict\";\n\n\tvar proto = DOMParser.prototype, \n nativeParse = proto.parseFromString;\n\n\t// Firefox/Opera/IE trigger errors for unsupported types\n\ttry {\n\t\t// WebKit returns null for unsupported types\n\t\tif ((new DOMParser()).parseFromString(\"\", \"text/html\")) {\n\t\t\t// text/html natvely supported\n\t\t\treturn;\n\t\t}\n\t} catch (ex) {}\n\n\tproto.parseFromString = function(markup, type) {\n\t\tif (/^\\s*text\\/html\\s*(?:;|$)/i.test(type)) {\n\t\t\tvar doc = document.implementation.createHTMLDocument(\"\");\n\t\t\t\n\t\t\tif (markup.toLowerCase().indexOf('<!doctype') > -1) {\n\t\t\t\tdoc.documentElement.innerHTML = markup;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdoc.body.innerHTML = markup;\n\t\t\t}\n\t\t\treturn doc;\n\t\t} else {\n\t\t\treturn nativeParse.apply(this, arguments);\n\t\t}\n\t};\n}(DOMParser));\ndefine(\"utils/dom\", function(){});\n\n",
|
|
44
|
-
"/**\n * ValidatorPlugin\n *\n * Dependencies:\n * - utils/form-validator\n * - utils/merge\n * - utils/events\n * - vendor/uuid\n * \n * Additional helpers for the backend are located in framwework/v{version}/helpers/plugins/validator-*.js\n * \n * At Form Level \n * - data-gina-form-live-check-enabled\n * - data-gina-form-required-before-submit\n * \n * @param {object} rule\n * @param {object} [ data ] // from request\n * @param {string} [ formId ]\n * */\n function ValidatorPlugin(rules, data, formId) {\n\n this.plugin = 'validator';\n\n /**\n * validator event handler - isGFFCtx only\n * */\n var events = [\n 'init', // form or popin init\n 'ready',\n 'registered',\n 'success',\n 'error',\n 'progress',\n 'submit',\n 'reset',\n 'change',\n 'changed',\n 'keydown', // for autocomplete\n 'keyup', // for autocomplete\n 'focusout',\n 'focusin',\n 'validate', // for form livecheck (validation)\n 'validated', // for form livecheck (validation)\n 'destroy',\n 'asyncCompleted'\n ];\n \n // See: https://developer.mozilla.org/fr/docs/Web/HTML/Element/Input\n var allowedLiveInputTypes = [\n 'radio',\n 'checkbox',\n \n 'text',\n 'hidden',\n 'password',\n 'number', // not supporting float\n 'date',\n 'email',\n // extended types\n 'search',\n 'color',\n 'tel',\n 'range',\n 'time',\n 'datetime-local',\n 'datetime', // deprecated\n 'month',\n 'week',\n 'url'\n ];\n\n /** imports */\n var isGFFCtx = ( ( typeof(module) !== 'undefined' ) && module.exports ) ? false : true;\n var envIsDev = null;\n if (isGFFCtx) {\n require('utils/events');\n registerEvents(this.plugin, events);\n\n require('utils/dom');\n require('utils/effects');\n \n envIsDev = gina.config.envIsDev;\n } else {\n envIsDev = (/^true$/i.test(process.env.NODE_ENV_IS_DEV)) ? true : false;\n if (envIsDev) {\n delete require.cache[require.resolve('./form-validator')]\n }\n }\n\n var uuid = (isGFFCtx) ? require('vendor/uuid') : require('uuid');\n var merge = (isGFFCtx) ? require('utils/merge') : require('../../../../../lib/merge');\n var inherits = (isGFFCtx) ? require('utils/inherits') : require('../../../../../lib/inherits');\n var FormValidator = (isGFFCtx) ? require('utils/form-validator') : require('./form-validator');\n //var Collection = (isGFFCtx) ? require('utils/collection') : require('../../../../../lib/collection');\n var routing = (isGFFCtx) ? require('utils/routing') : require('../../../../../lib/routing');\n \n /** definitions */\n var instance = { \n 'id' : 'validator-' + uuid.v4(),\n\n 'plugin' : this.plugin,\n 'on' : (isGFFCtx) ? on : null,\n 'eventData' : {},\n 'target' : (isGFFCtx) ? document : null, // by default\n 'errors' : {},\n 'initialized' : false,\n 'isReady' : false,\n 'rules' : {},\n '$forms' : {},\n 'getFormById' : null,\n 'validateFormById' : null,\n 'setOptions' : null,\n 'resetErrorsDisplay': null,\n 'resetFields' : null\n };\n\n // validator proto\n var $validator = { // isGFFCtx only\n 'id' : null, // form id\n\n 'plugin' : this.plugin,\n 'on' : (isGFFCtx) ? on : null,\n 'eventData' : {},\n 'target' : (isGFFCtx) ? document : null, // by default\n 'cachedErrors' : {},\n 'binded' : false,\n 'unbinded' : false,\n 'withUserBindings' : false,\n 'rules' : {},\n 'setOptions' : null,\n 'send' : null,\n 'isValidating' : null,\n 'isSubmitting' : null,\n 'submit' : null,\n 'destroy' : null,\n 'resetErrorsDisplay' : null,\n 'resetFields' : null\n };\n /**@js_externs local*/\n var local = {\n 'rules': {}\n };\n \n var keyboardMapping = {};\n\n /**\n * XML Request - isGFFCtx only\n * */\n var xhr = null;\n var xhrOptions = {\n 'url' : '',\n 'method' : 'GET',\n 'isSynchrone' : false,\n 'withCredentials': false,\n 'headers' : {\n // to upload, use `multipart/form-data` for `enctype`\n 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n // cross domain is enabled by default, but you need to setup `Access-Control-Allow-Origin`\n 'X-Requested-With': 'XMLHttpRequest' // in case of cross domain origin\n\n }\n };\n\n /**\n * backend definitions\n * */\n var setCustomRules = function (customRules) {\n // parsing rules\n if ( typeof(customRule) != 'undefined' ) {\n try {\n parseRules(customRule, '');\n customRule = checkForRulesImports(customRule);\n } catch (err) {\n throw err\n }\n }\n }\n\n var backendProto = {\n 'setCustomRules': setCustomRules\n };\n\n\n /**\n * Backend init\n *\n * @param {object} rules\n * @param {object} [customRule]\n * */\n var backendInit = function (rules, data, formId) {\n\n var $form = ( typeof(formId) != 'undefined' ) ? { 'id': formId } : null;\n var fields = {};\n \n for (var field in data) {\n fields[field] = data[field]\n }\n\n\n // parsing rules\n if ( typeof(rules) != 'undefined' && rules.count() > 0 ) {\n \n try {\n parseRules(rules, '');\n rules = checkForRulesImports(rules);\n } catch (err) {\n throw err\n }\n \n backendProto.rules = instance.rules;\n\n return validate($form, fields, null, instance.rules)\n\n } else {\n // without rules - by hand\n return new FormValidator(fields)\n }\n }\n\n\n /**\n * GFF definitions\n * */\n var setOptions = function (options) {\n options = merge(options, xhrOptions);\n xhrOptions = options;\n }\n\n\n var getFormById = function(formId) {\n var $form = null, _id = formId;\n\n if ( !instance['$forms'] )\n throw new Error('`$forms` collection not found');\n\n if ( typeof(_id) == 'undefined') {\n throw new Error('[ FormValidator::getFormById(formId) ] `formId` is missing')\n }\n\n _id = _id.replace(/\\#/, ''); \n \n // in case form is created on the fly and is not yet registered\n if (document.getElementById(_id) != null && typeof (instance['$forms'][_id]) == 'undefined') {\n initForm( document.getElementById(_id) );\n } \n \n if ( typeof(instance.$forms[_id]) != 'undefined' ) { \n instance['$forms'][_id].withUserBindings = true;\n \n if ( typeof(this.$forms) != 'undefined' && typeof(this.$forms[_id]) == 'undefined' ) { \n $form = this.$forms[_id] = instance['$forms'][_id];\n } else {\n $form = instance.$forms[_id];\n } \n } \n \n if (!$form) {\n throw new Error('Validator::getFormById(...) exception: could not retrieve form `'+ _id +'`');\n }\n \n if ( !$form.binded) {\n var $target = $form.target;\n bindForm($target);\n $form = instance.$forms[_id];\n }\n \n \n \n // update toolbar\n if ( envIsDev && isGFFCtx && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar ) {\n // update toolbar\n if (!gina.forms.errors)\n gina.forms.errors = {};\n\n var objCallback = {\n id : _id,\n rules : instance.$forms[_id].rules\n };\n if ( typeof(instance.$forms[_id].errors) != 'undefined' ) {\n objCallback.errors = instance.$forms[_id].errors\n }\n\n window.ginaToolbar.update('forms', objCallback);\n }\n\n return $form;\n }\n \n /**\n * isPopinContext\n * \n * @returns {boolean} isPopinContext\n */\n var isPopinContext = function() {\n var isPopinInUse = false, $activePopin = null;\n \n if ( gina.hasPopinHandler && gina.popinIsBinded ) {\n $activePopin = gina.popin.getActivePopin();\n }\n \n if ( $activePopin && $activePopin.isOpen ) {\n isPopinInUse = true;\n }\n \n return isPopinInUse;\n }\n\n\n /**\n * validateFormById\n *\n * @param {string} formId\n * @param {object} [customRule]\n *\n * @returns {object} $form\n * */\n var validateFormById = function(formId, customRule) {\n var $form = null\n , _id = formId\n , rules = ( typeof(local.rules.count() > 0 ) ) ? local.rules : instance.rules\n , $target = null\n ;\n \n if ( !instance['$forms'] ) {\n throw new Error('`$forms` collection not found')\n }\n // Return existing when available\n if ( typeof(_id) != 'undefined' && typeof(instance.$forms[_id]) != 'undefined' ) {\n return instance.$forms[_id];\n }\n\n if ( typeof(_id) == 'undefined' ) {\n if ( typeof(this.id) != 'undefined' && this.id != '' && this.id != null ) {\n _id = this.id\n } else {\n throw new Error('[ FormValidator::validateFormById(formId, customRule) ] `formId` is missing')\n }\n }\n\n if ( typeof(_id) == 'string') {\n _id = _id.replace(/\\#/, '')\n } else if ( typeof(_id) == 'object' && !Array.isArray(_id) ) { // weird exception\n\n $target = _id.form;\n _id = $target.getAttribute('id') || 'form.'+uuid.v4();\n\n $target.setAttribute('id', _id);// just in case\n\n } else {\n throw new Error('[ FormValidator::validateFormById(formId[, customRule]) ] `formId` should be a `string`');\n }\n\n checkForDuplicateForm(_id);\n \n if ( typeof(this.$forms) != 'undefined' && typeof(instance['$forms'][_id]) != 'undefined' ) { \n $form = this.$forms[_id] = instance['$forms'][_id];\n } else { // binding a form out of context (outside of the main instance)\n $target = document.getElementById(_id);\n $validator.id = _id;\n $validator.target = $target;\n\n $form = this.$forms[_id] = instance.$forms[_id] = merge({}, $validator);\n\n var rule = null;\n if ( typeof(customRule) == 'undefined') {\n rule = _id.replace(/\\-/g, '.');\n\n if ( typeof(rules) != 'undefined' ) {\n $form['rule'] = customRule = getRuleObjByName(rule)\n } else if ( typeof($form.target) != 'undefined' && $form.target !== null && $form.target.getAttribute('data-gina-form-rule') ) {\n rule = $form.target.getAttribute('data-gina-form-rule').replace(/\\-|\\//g, '.');\n\n if ( typeof(rules) != 'undefined' ) {\n $form['rule'] = getRuleObjByName(rule)\n } else {\n throw new Error('[ FormValidator::validateFormById(formId) ] using `data-gina-form-rule` on form `'+$form.target+'`: no matching rule found')\n }\n } // no else to allow form without any rule\n } else {\n rule = customRule.replace(/\\-|\\//g, '.');\n\n if ( typeof(rules) != 'undefined' ) {\n $form['rule'] = getRuleObjByName(rule)\n } else {\n throw new Error('[ FormValidator::validateFormById(formId, customRule) ] `'+customRule+'` is not a valid rule')\n }\n }\n \n if ( $target && typeof(this.isPopinContext) != 'undefined' && /true/i.test(this.isPopinContext) ) {\n $target.isPopinContext = this.isPopinContext;\n }\n \n if ($target && !$form.binded)\n bindForm($target, rule);\n }\n \n \n\n if (!$form) throw new Error('[ FormValidator::validateFormById(formId, customRule) ] `'+_id+'` not found');\n\n return $form || null;\n\n }\n \n var refreshWarning = function($el) {\n var formId = $el.form.getAttribute('id');\n if ( /^true$/i.test(instance.$forms[formId].isValidating) ) {\n return;\n }\n \n var $parent = $el.parentNode, isErrorMessageHidden = false;\n var $children = $parent.getElementsByTagName('div');\n \n if ( /form\\-item\\-warning/.test($parent.className) ) {\n $parent.className = $parent.className.replace(/form\\-item\\-warning/, 'form-item-error');\n \n } else if (/form\\-item\\-error/.test($parent.className) ) { \n $parent.className = $parent.className.replace(/form\\-item\\-error/, 'form-item-warning');\n isErrorMessageHidden = true;\n }\n \n\n for (var c = 0, cLen = $children.length; c<cLen; ++c) {\n if ( /form\\-item\\-error\\-message/.test($children[c].className) ) {\n if (isErrorMessageHidden) {\n // hide error messages\n $children[c].className = $children[c].className +' hidden';\n } else {\n // display error messages\n $children[c].className = $children[c].className.replace(/(\\s+hidden|hidden)/, '');\n }\n break\n }\n }\n }\n\n /**\n * handleErrorsDisplay\n * Attention: if you are going to handle errors display by hand, set data to `null` to prevent Toolbar refresh with empty data\n * @param {object} $form - Target (HTMLFormElement)\n * @param {object} errors \n * @param {object|null} data\n * @param {object|null} [fileName]\n */\n var liveCheckErrors = {}; // Per Form & Per Element\n var handleErrorsDisplay = function($form, errors, data, fieldName) {\n \n // Toolbar errors display\n if ( envIsDev )\n var formsErrors = null;\n \n var errorClass = 'form-item-error' // by default\n , isWarning = false\n ; \n // catch reset\n if ( \n typeof($form.dataset.ginaFormIsResetting) != 'undefined' \n && /^(true)$/i.test($form.dataset.ginaFormIsResetting) \n ) {\n errors = {};\n liveCheckErrors = {};\n // restore default\n $form.dataset.ginaFormIsResetting = false;\n } else {\n // Live check enabled ?\n if ( \n /^(true)$/i.test($form.dataset.ginaFormLiveCheckEnabled) \n && typeof(fieldName) != 'undefined'\n ) {\n var formId = ( typeof($form.id) != 'string' ) ? $form.getAttribute('id') : $form.id;\n if ( typeof(liveCheckErrors[formId]) == 'undefined') {\n liveCheckErrors[formId] = {};\n } \n if (errors.count() > 0) {\n // reset field name\n liveCheckErrors[formId][fieldName] = {};\n // override\n liveCheckErrors[formId][fieldName] = merge(errors[fieldName], liveCheckErrors[formId][fieldName]);\n if (liveCheckErrors[formId][fieldName].count() == 0) {\n delete liveCheckErrors[formId][fieldName]\n }\n errors = liveCheckErrors[formId];\n // only if the form has not been sent yet\n if (!instance.$forms[formId].sent || instance.$forms[formId].isValidating) {\n isWarning = true;\n }\n } else {\n if ( typeof(liveCheckErrors[formId][fieldName]) != 'undefined') {\n delete liveCheckErrors[formId][fieldName];\n if ( \n typeof(window.gina.validator.$forms[formId].errors) != 'undefined'\n && typeof(window.gina.validator.$forms[formId].errors[fieldName]) != 'undefined'\n ) {\n delete window.gina.validator.$forms[formId].errors[fieldName];\n }\n }\n if ( \n typeof(instance.$forms) != 'undefined'\n && typeof(instance.$forms[formId]) != 'undefined' \n && typeof(instance.$forms[formId].errors) != 'undefined' \n && instance.$forms[formId].errors.count() == 0 \n ) {\n // update submit trigger state\n updateSubmitTriggerState( $form, true );\n }\n \n if ( typeof(liveCheckErrors[formId]) != 'undefined' && liveCheckErrors[formId].count() == 0 ) {\n delete liveCheckErrors[formId]\n } else {\n errors = liveCheckErrors[formId];\n }\n \n \n }\n }\n }\n \n \n var name = null, errAttr = null;\n var $err = null, $msg = null;\n var $el = null, $parent = null, $target = null;\n var id = $form.getAttribute('id');\n // TODO - Refacto on this may be done later since we are doing nothing with it\n data = ( typeof(data) != 'undefined' ) ? data : {};\n\n for (var i = 0, len = $form.length; i<len; ++i) {\n \n $el = $form[i];\n \n if (typeof(fieldName) != 'undefined' && fieldName != $el.name) continue;\n \n if ( /form\\-item\\-wrapper$/.test($el.parentNode.className) ) {\n $parent = $el.parentNode.parentNode;\n $target = $el.parentNode;\n } else {\n $parent = $el.parentNode;\n $target = $el;\n }\n\n name = $el.getAttribute('name');\n errAttr = $el.getAttribute('data-gina-form-errors');\n\n if (!name) continue;\n\n if ( typeof(errors[name]) != 'undefined' && !/(form\\-item\\-error|form\\-item\\-warning)/.test($parent.className) ) {\n \n if (isWarning) {\n // adding warning class\n $parent.className += ($parent.className == '' ) ? 'form-item-warning' : ' form-item-warning';\n } else {\n //$parent.className = $parent.className.replace(/(\\s+form\\-item\\-warning|form\\-item\\-warning)/, '');\n $parent.className += ($parent.className == '' ) ? 'form-item-error' : ' form-item-error';\n }\n $err = document.createElement('div');\n if (isWarning) {\n //$err.setAttribute('class', 'form-item-error-message hidden');\n $err.className = 'form-item-error-message hidden';\n } else {\n //$err.setAttribute('class', 'form-item-error-message');\n $err.className = 'form-item-error-message';\n }\n \n // injecting error messages\n for (var e in errors[name]) {\n\n if (e != 'stack') { // ignore stack for display\n $msg = document.createElement('p');\n $msg.appendChild( document.createTextNode(errors[name][e]) );\n $err.appendChild($msg);\n }\n\n if ( envIsDev ) {\n if (!formsErrors) formsErrors = {};\n if ( !formsErrors[ name ] )\n formsErrors[ name ] = {};\n \n formsErrors[ name ][e] = errors[name][e]\n }\n }\n \n if ($target.type != 'hidden')\n insertAfter($target, $err);\n\n \n\n } else if ( typeof(errors[name]) == 'undefined' && /(form\\-item\\-error|form\\-item\\-warning)/.test($parent.className) || typeof(errors[name]) != 'undefined' && errors[name].count() == 0 && /(form\\-item\\-error|form\\-item\\-warning)/.test($parent.className) ) {\n // reset when not in error\n // remove child elements\n var $children = $parent.getElementsByTagName('div');\n for (var c = 0, cLen = $children.length; c<cLen; ++c) {\n if ( /form\\-item\\-error\\-message/.test($children[c].className) ) {\n $children[c].parentElement.removeChild($children[c]);\n break\n }\n \n }\n\n $parent.className = $parent.className.replace(/(\\s+form\\-item\\-error|form\\-item\\-error|\\s+form\\-item\\-warning|form\\-item\\-warning)/, '');\n\n } else if ( typeof(errors[name]) != 'undefined' && errAttr) {\n // refreshing already displayed error on msg update\n var $divs = $parent.getElementsByTagName('div');\n for (var d = 0, dLen = $divs.length; d<dLen; ++d) {\n if ($divs[d].className == 'form-item-error-message') {\n\n $divs[d].parentElement.removeChild($divs[d]);\n $err = document.createElement('div');\n $err.setAttribute('class', 'form-item-error-message');\n\n // injecting error messages\n // {\n // field: {\n // rule: errorMsg\n // }\n // }\n for (var e in errors[name]) {\n $msg = document.createElement('p');\n $msg.appendChild( document.createTextNode(errors[name][e]) );\n $err.appendChild($msg);\n\n if ( envIsDev ) {\n if (!formsErrors) formsErrors = {};\n if ( !formsErrors[ name ] )\n formsErrors[ name ] = {};\n\n formsErrors[ name ][e] = errors[name][e]\n }\n }\n\n break;\n }\n }\n\n if ($err && $target.type != 'hidden')\n insertAfter($target, $err);\n\n }\n \n if (typeof(fieldName) != 'undefined' && fieldName === $el.name) break;\n }\n\n\n var objCallback = null;\n if ( formsErrors ) {\n\n triggerEvent(gina, $form, 'error.' + id, errors)\n\n if ( envIsDev && isGFFCtx && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar ) {\n // update toolbar\n if (!gina.forms.errors)\n gina.forms.errors = {};\n\n objCallback = {\n id : id,\n errors : formsErrors\n };\n\n window.ginaToolbar.update('forms', objCallback);\n }\n } else if ( envIsDev && isGFFCtx && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar) { // reset toolbar form errors\n if (!gina.forms.errors)\n gina.forms.errors = {};\n\n objCallback = {\n id: id,\n errors: {}\n };\n if (isGFFCtx)\n window.ginaToolbar.update('forms', objCallback);\n }\n\n if (\n gina \n && isGFFCtx \n && envIsDev\n && instance.$forms[id].isSubmitting\n && /^true$/i.test(instance.$forms[id].isSubmitting) \n && typeof(window.ginaToolbar) != 'undefined' \n && window.ginaToolbar \n && data\n ) {\n \n try {\n // update toolbar\n window.ginaToolbar.update('data-xhr', data);\n\n } catch (err) {\n throw err\n }\n }\n\n }\n\n\n /**\n * Reset errors display\n *\n * @param {object|string} $formOrFormId [$formInstance|$formInstance.target|$formInstance.id]\n *\n * */\n var resetErrorsDisplay = function($formOrFormId) {\n var _id = null, $form = null;\n if ( typeof($formOrFormId) == 'undefined' && typeof(this.id) != 'undefined' ) {\n $formOrFormId = this.id;\n }\n if ( /^string$/i.test(typeof($formOrFormId)) ) {\n _id = $formOrFormId.replace(/\\#/, '');\n $form = document.getElementById(_id);\n } else if ( $formOrFormId instanceof HTMLFormElement ) {\n $form = $formOrFormId\n } else if ( /^object$/i.test(typeof($formOrFormId)) ) {\n $form = $formOrFormId.target;\n }\n \n if (!$form) {\n throw new Error('[ FormValidator::resetErrorsDisplay([ formId | <form> ]) ] `'+$formOrFormId+'` not found')\n }\n \n // Resetting error display\n $form.dataset.ginaFormIsResetting = true;\n handleErrorsDisplay($form, {});\n \n\n return $form\n }\n\n /**\n * Reset fields\n *\n * @param {object|string} [$form|formId]\n *\n * */\n var resetFields = function($form) {\n var _id = null;\n if ( typeof($form) == 'undefined' ) {\n if ( typeof(this.target) != 'undefined' ) {\n _id = this.target.getAttribute('id');\n } else {\n _id = this.getAttribute('id');\n }\n\n $form = instance.$forms[_id]\n } else if ( typeof($form) == 'string' ) {\n _id = $form;\n _id = _id.replace(/\\#/, '');\n\n if ( typeof(instance.$forms[_id]) == 'undefined') {\n throw new Error('[ FormValidator::resetErrorsDisplay([formId]) ] `'+$form+'` not found')\n }\n\n $form = instance.$forms[_id]\n }\n\n if ($form.fieldsSet) {\n\n var elId = null\n , $element = null\n , tagName = null\n , type = null\n , value = null // current value\n , defaultValue = null\n ;\n\n for (var f in $form.fieldsSet) {\n\n $element = document.getElementById(f);\n type = $element.tagName.toLowerCase();\n tagName = $element.tagName;\n \n if ( /textarea/i.test(tagName) ) {\n defaultValue = $form.fieldsSet[f].defaultValue;\n $element.value = defaultValue;\n triggerEvent(gina, $element, 'change');\n continue;\n }\n\n if (type == 'input') {\n \n defaultValue = $form.fieldsSet[f].defaultValue;\n \n if (/$(on|true|false)$/i.test(defaultValue)) {\n defaultValue = (/$(on|true)$/i.test(defaultValue)) ? true : false;\n }\n \n if ( /^(checkbox|radio)$/i.test($element.type) ) {\n $element.checked = $form.fieldsSet[f].defaultChecked;\n } else if ( !/^(checkbox|radio)$/i.test($element.type) ) {\n $element.value = defaultValue;\n }\n triggerEvent(gina, $element, 'change');\n \n } else if ( type == 'select' ) {\n defaultValue = $form.fieldsSet[f].selectedIndex || 0;\n $element.selectedIndex = defaultValue;\n $element.dataset.value = $element.options[ $element.selectedIndex ].value;\n triggerEvent(gina, $element, 'change');\n }\n \n }\n }\n\n return $form\n }\n\n var submit = function () {\n\n var $form = null, _id = null, $target = null;\n\n if ( typeof(this.getAttribute) != 'undefined' ) {\n _id = this.getAttribute('id');\n $target = this;\n } else if ( typeof(this.target) != 'undefined' && this.target != null && typeof(this.target.getAttribute) != 'undefined' ) {\n _id = this.target.getAttribute('id');\n $target = this.target\n }\n\n if ( typeof(instance.$forms[_id]) == 'undefined') {\n throw new Error('[ FormValidator::submit() ] not `$form` binded. Use `FormValidator::getFormById(id)` or `FormValidator::validateFormById(id)` first ')\n }\n\n triggerEvent(gina, $target, 'submit');\n\n return this;\n }\n \n \n\n /**\n * send\n * N.B.: no validation here; if you want to validate against rules, use `.submit()` before\n *\n *\n * @param {object} data\n * @param {object} [ options ] : { isSynchrone: true, withCredentials: true }\n * */\n var send = function(data, options) {\n \n \n var $target = this.target , id = $target.getAttribute('id');\n var $form = instance.$forms[id] || this;\n var result = null;\n var XHRData = null;\n var isAttachment = null; // handle download\n var hFormIsRequired = null;\n \n if ( \n typeof($form.isSending) != 'undefined'\n && /^true$/i.test($form.isSending)\n ||\n typeof($form.sent) != 'undefined'\n && /^true$/i.test($form.sent)\n ) {\n return;\n }\n instance.$forms[id].isSending = true;\n \n \n options = (typeof (options) != 'undefined') ? merge(options, xhrOptions) : xhrOptions;\n // `x-gina-form`definition\n //options.headers['X-Gina-Form-Location'] = gina.config.bundle;\n if ( typeof($form.id) != 'undefined' ) {\n options.headers['X-Gina-Form-Id'] = $form.id;\n if ( \n typeof(gina.forms.rules) != 'undefined' \n && $form.rules.count() > 0\n && typeof($form.rules[$form.id]) != 'undefined'\n ) {\n options.headers['X-Gina-Form-Rule'] = $form.id +'@'+ gina.config.bundle;\n } \n }\n // if ( typeof($form.name) != 'undefined' ) {\n // options.headers['X-Gina-Form-Name'] = $form.name;\n // } \n if ( typeof($form.target.dataset.ginaFormRule) != 'undefined' ) {\n options.headers['X-Gina-Form-Rule'] = $form.target.dataset.ginaFormRule +'@'+ gina.config.bundle;\n } \n \n \n // forward callback to HTML data event attribute through `hform` status\n hFormIsRequired = ( $target.getAttribute('data-gina-form-event-on-submit-success') || $target.getAttribute('data-gina-form-event-on-submit-error') ) ? true : false;\n // success -> data-gina-form-event-on-submit-success\n // error -> data-gina-form-event-on-submit-error\n if (hFormIsRequired)\n listenToXhrEvents($form);\n\n var url = $target.getAttribute('action') || options.url;\n var method = $target.getAttribute('method') || options.method;\n method = method.toUpperCase();\n options.method = method;\n options.url = url;\n \n if (!xhr) {\n xhr = setupXhr(options);\n }\n\n // to upload, use `multipart/form-data` for `enctype`\n var enctype = $target.getAttribute('enctype') || options.headers['Content-Type'];\n \n\n if ( options.withCredentials ) {\n\n if ('withCredentials' in xhr) {\n // XHR for Chrome/Firefox/Opera/Safari.\n if (options.isSynchrone) {\n xhr.open(options.method, options.url, options.isSynchrone)\n } else {\n xhr.open(options.method, options.url)\n }\n } else if ( typeof XDomainRequest != 'undefined' ) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n xhr.open(options.method, options.url);\n } else {\n // CORS not supported.\n xhr = null;\n result = 'CORS not supported: the server is missing the header `\"Access-Control-Allow-Credentials\": true` ';\n triggerEvent(gina, $target, 'error.' + id, result);\n\n return\n }\n \n if ( typeof(options.responseType) != 'undefined' ) {\n xhr.responseType = options.responseType;\n } else {\n xhr.responseType = '';\n }\n\n xhr.withCredentials = true;\n } else {\n if (options.isSynchrone) {\n xhr.open(options.method, options.url, options.isSynchrone)\n } else {\n xhr.open(options.method, options.url)\n }\n }\n\n // setting up headers - all but Content-Type ; it will be set right before .send() is called\n for (var hearder in options.headers) {\n //if ( hearder == 'Content-Type' && typeof (enctype) != 'undefined' && enctype != null && enctype != '') {\n // options.headers[hearder] = enctype\n //}\n if (hearder == 'Content-Type' && typeof (enctype) != 'undefined' && enctype != null && enctype != '')\n continue;\n\n xhr.setRequestHeader(hearder, options.headers[hearder]);\n }\n \n if (xhr) {\n // catching ready state cb\n //handleXhrResponse(xhr, $target, id, $form, hFormIsRequired);\n xhr.onreadystatechange = function onValidationCallback(event) {\n $form.isSubmitting = false;\n $form.isSending = false;\n \n // limit send trigger to 1 sec to prevent from double clicks\n setTimeout( function onSent() {\n $form.sent = false;\n }, 1000);\n \n // In case the user is also redirecting\n var redirectDelay = (/Google Inc/i.test(navigator.vendor)) ? 50 : 0;\n \n if (xhr.readyState == 2) { // responseType interception\n isAttachment = ( /^attachment\\;/.test( xhr.getResponseHeader(\"Content-Disposition\") ) ) ? true : false; \n // force blob response type\n if ( !xhr.responseType && isAttachment ) {\n xhr.responseType = 'blob';\n }\n }\n\n if (xhr.readyState == 4) {\n var blob = null;\n var contentType = xhr.getResponseHeader(\"Content-Type\"); \n \n // 200, 201, 201' etc ...\n if( /^2/.test(xhr.status) ) {\n\n try { \n \n // handling blob xhr download\n if ( /blob/.test(xhr.responseType) || isAttachment ) {\n if ( typeof(contentType) == 'undefined' || contentType == null) {\n contentType = 'application/octet-stream';\n }\n \n blob = new Blob([this.response], { type: contentType });\n \n //Create a link element, hide it, direct it towards the blob, and then 'click' it programatically\n var a = document.createElement('a');\n a.style = \"display: none\";\n document.body.appendChild(a);\n //Create a DOMString representing the blob and point the link element towards it\n var url = window.URL.createObjectURL(blob);\n a.href = url;\n var contentDisposition = xhr.getResponseHeader(\"Content-Disposition\");\n a.download = contentDisposition.match('\\=(.*)')[0].substr(1);\n //programatically click the link to trigger the download\n a.click();\n //release the reference to the file by revoking the Object URL\n window.URL.revokeObjectURL(url);\n \n result = {\n status : xhr.status,\n statusText: xhr.statusText,\n responseType: blob.type,\n type : blob.type,\n size : blob.size \n }\n \n } else { // normal case\n result = xhr.responseText; \n }\n \n\n \n if ( /\\/json/.test( contentType ) ) {\n result = JSON.parse(xhr.responseText);\n \n if ( typeof(result.status) == 'undefined' )\n result.status = xhr.status;\n \n }\n \n if ( /\\/html/.test( contentType ) ) {\n \n result = {\n contentType : contentType,\n content : xhr.responseText\n };\n \n if ( typeof(result.status) == 'undefined' )\n result.status = xhr.status;\n \n // if hasPopinHandler & popinIsBinded\n if ( typeof(gina.popin) != 'undefined' && gina.hasPopinHandler ) { \n // select popin current active popin\n var $popin = gina.popin.getActivePopin();\n \n if ($popin) {\n \n XHRData = {};\n // update toolbar\n \n try {\n XHRData = new DOMParser().parseFromString(result.content, 'text/html').getElementById('gina-without-layout-xhr-data');\n XHRData = JSON.parse(decodeURIComponent(XHRData.value));\n \n XHRView = new DOMParser().parseFromString(result.content, 'text/html').getElementById('gina-without-layout-xhr-view'); \n XHRView = JSON.parse(decodeURIComponent(XHRView.value));\n \n // update data tab \n if ( gina && envIsDev && typeof(window.ginaToolbar) && typeof(XHRData) != 'undefined' ) {\n window.ginaToolbar.update(\"data-xhr\", XHRData);\n }\n \n // update view tab\n \n if ( gina && envIsDev && typeof(window.ginaToolbar) && typeof(XHRView) != 'undefined' ) {\n window.ginaToolbar.update(\"view-xhr\", XHRView);\n } \n\n } catch (err) {\n throw err\n }\n \n \n $popin.loadContent(result.content);\n \n result = XHRData;\n triggerEvent(gina, $target, 'success.' + id, result);\n \n return;\n }\n }\n }\n \n $form.eventData.success = result;\n\n XHRData = result;\n // update toolbar\n if ( gina && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar && XHRData ) {\n try {\n // don't refresh for html datas\n if ( envIsDev && typeof(XHRData) != 'undefined' && /\\/html|\\/json/.test(contentType) ) {\n window.ginaToolbar.update(\"data-xhr\", XHRData);\n }\n\n } catch (err) {\n throw err\n }\n }\n\n // intercepts upload\n if ( /^gina\\-upload/i.test(id) )\n onUpload(gina, $target, 'success', id, result);\n \n // intercepts result.popin & popin redirect (from SuperController::redirect() )\n var isXhrRedirect = false;\n if (\n typeof(result.isXhrRedirect) != 'undefined'\n && /^true$/i.test(result.isXhrRedirect)\n ) {\n isXhrRedirect = true;\n }\n if ( \n typeof(gina.popin) != 'undefined'\n && gina.hasPopinHandler\n && typeof(result.popin) != 'undefined'\n ||\n typeof(gina.popin) != 'undefined'\n && gina.hasPopinHandler\n && typeof(result.location) != 'undefined'\n && isXhrRedirect\n ) {\n var $popin = gina.popin.getActivePopin();\n if ( !$popin && typeof(result.popin) != 'undefined' ) {\n if ( typeof(result.popin) != 'undefined' && typeof(result.popin.name) == 'undefined' ) {\n throw new Error('To get a `$popin` instance, you need at list a `popin.name`.');\n }\n $popin = gina.popin.getPopinByName(result.popin.name);\n if ( !$popin ) {\n throw new Error('Popin with name: `'+ result.popin.name +'` not found.')\n }\n }\n \n if ( \n typeof(result.popin) != 'undefined' \n && typeof(result.popin.close) != 'undefined'\n ) {\n $popin.isRedirecting = false;\n $popin.close();\n var _reload = (result.popin.reload) ? result.popin.reload : false;\n if ( !result.popin.location && !result.popin.url) {\n delete result.popin;\n // only exception\n if (_reload) {\n result.popin = { reload: _reload };\n }\n }\n }\n \n if ( \n typeof(result.popin) != 'undefined'\n && typeof(result.popin.location) != 'undefined'\n ||\n typeof(result.popin) != 'undefined'\n && typeof(result.popin.url) != 'undefined'\n ||\n typeof(result.location) != 'undefined'\n && isXhrRedirect\n ) { \n var popinName = null;\n if ( $popin ) {\n popinName = $popin.name; // by default\n $popin.isRedirecting = true;\n }\n \n var _target = '_self'; // by default\n if ( typeof(result.popin) != 'undefined' && typeof(result.popin.target) != 'undefined' ) {\n if ( /^(blank|self|parent|top)$/ ) {\n result.popin.target = '_'+result.popin.target;\n }\n _target = result.popin.target\n } \n \n //var popinUrl = (typeof(result.popin) != 'undefined') ? result.popin.location : result.location;\n var popinUrl = result.location || result.popin.location || result.popin.url;\n if ( \n typeof(result.popin) != 'undefined'\n && typeof(result.popin.name) != 'undefined'\n && popinName != result.popin.name\n ) {\n //$popin = gina.popin.getActivePopin();\n if ($popin)\n $popin.close();\n \n popinName = result.popin.name;\n $popin = gina.popin.getPopinByName(popinName);\n if ( !$popin ) {\n throw new Error('Popin with name `'+ popinName+'` not found !');\n }\n $popin.load($popin.name, popinUrl, $popin.options);\n } else if ($popin) {\n $popin.load($popin.name, popinUrl, $popin.options);\n }\n if ($popin) {\n return setTimeout( function onPopinredirect($popin){\n if (!$popin.isOpen) {\n $popin.open();\n return;\n }\n }, 50, $popin);\n } \n }\n }\n \n triggerEvent(gina, $target, 'success.' + id, result); \n \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'success.' + id + '.hform', result);\n \n } catch (err) {\n\n result = {\n status: 422,\n error : err.message,\n stack : err.stack\n\n };\n\n $form.eventData.error = result;\n \n\n XHRData = result; \n // update toolbar\n if ( gina && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar && XHRData ) {\n try {\n\n if ( envIsDev && typeof(XHRData) != 'undefined' ) {\n window.ginaToolbar.update(\"data-xhr\", XHRData);\n }\n\n } catch (err) {\n throw err\n }\n }\n \n // intercept upload\n if ( /^gina\\-upload/i.test(id) )\n onUpload(gina, $target, 'error', id, result);\n \n triggerEvent(gina, $target, 'error.' + id, result);\n \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hform', result);\n }\n \n // handle redirect\n if ( typeof(result) != 'undefined' && typeof(result.location) != 'undefined' ) { \n window.location.hash = ''; //removing hashtag \n \n // if ( window.location.host == gina.config.hostname && /^(http|https)\\:\\/\\//.test(result.location) ) { // same origin\n // result.location = result.location.replace( new RegExp(gina.config.hostname), '' );\n // } else { // external - need to remove `X-Requested-With` from `options.headers`\n result.location = (!/^http/.test(result.location) && !/^\\//.test(result.location) ) ? location.protocol +'//' + result.location : result.location;\n //} \n \n return setTimeout(() => {\n window.location.href = result.location;\n }, redirectDelay); \n }\n\n } else if ( xhr.status != 0) {\n // XHR Error\n result = { 'status': xhr.status };\n // handling blob xhr error\n if ( /blob/.test(xhr.responseType) ) {\n \n blob = new Blob([this.response], { type: 'text/plain' });\n \n var reader = new FileReader(), blobError = '';\n \n \n // This fires after the blob has been read/loaded.\n reader.addEventListener('loadend', (e) => {\n \n if ( /string/i.test(typeof(e.srcElement.result)) ) {\n blobError += e.srcElement.result;\n // try {\n // result = merge( result, JSON.parse(blobError) )\n // } catch (err) {\n // result = merge(result, err)\n // }\n \n } else if ( typeof(e.srcElement.result) == 'object' ) {\n result = merge(result, e.srcElement.result)\n } else {\n result.message += e.srcElement.result\n }\n \n // once ready\n if ( /2/.test(reader.readyState) ) {\n \n if ( /^(\\{|\\[)/.test( blobError ) ) {\n try {\n result = merge( result, JSON.parse(blobError) )\n } catch(err) {\n result = merge(result, err)\n } \n }\n \n if (!result.message)\n delete result.message;\n // forward appplication errors to validator when available\n $form.eventData.error = result;\n\n // update toolbar\n XHRData = result;\n if ( gina && envIsDev && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar && XHRData ) {\n try {\n // update toolbar\n window.ginaToolbar.update('data-xhr', XHRData );\n\n } catch (err) {\n throw err\n }\n }\n \n // intercept upload\n if ( /^gina\\-upload/i.test(id) )\n onUpload(gina, $target, 'error', id, result);\n \n triggerEvent(gina, $target, 'error.' + id, result); \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hform', result);\n \n return;\n }\n \n \n });\n\n // Start reading the blob as text.\n reader.readAsText(blob);\n \n } else { // normal case\n \n if ( /^(\\{|\\[)/.test( xhr.responseText ) ) {\n\n try {\n result = merge( JSON.parse(xhr.responseText), result )\n } catch (err) {\n result = merge(err, result)\n }\n\n } else if ( typeof(xhr.responseText) == 'object' ) {\n result = merge(xhr.responseText, result)\n } else {\n result.message = xhr.responseText\n }\n \n // xhr error response (caching)\n //$form.eventData.error = result;\n // Forward appplication errors to forms.errors when available\n // This api error is meant for the Frontend Validation Errors Handling\n if ( typeof(result) != 'undefined' && typeof(result.error) != 'undefined' && result.fields && typeof(result.fields) == 'object') {\n \n var apiMessage = ( typeof(result.message) != 'undefined') ? result.message : null;\n var newResultfields = {};\n for (let f in result.fields) {\n let errorObject = {};\n errorObject[f] = {};\n errorObject[f].isApiError = result.fields[f];\n if ( apiMessage && !errorObject[f].isApiError) {\n errorObject[f].isApiError = result.error; // Generic error\n }\n newResultfields[f] = errorObject[f];\n handleErrorsDisplay($form.target, errorObject, data, f);\n \n }\n result.fields = newResultfields\n } \n $form.eventData.error = result;\n \n\n // update toolbar\n XHRData = result;\n if ( gina && envIsDev && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar && XHRData ) {\n try {\n // update toolbar\n window.ginaToolbar.update('data-xhr', XHRData );\n\n } catch (err) {\n throw err\n }\n }\n \n\n // intercept upload\n if ( /^gina\\-upload/i.test(id) )\n onUpload(gina, $target, 'error', id, result);\n \n triggerEvent(gina, $target, 'error.' + id, result); \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hform', result);\n \n \n \n }\n\n \n } /**else if ( xhr.readyState == 4 && xhr.status == 0 ) { // unknown error\n // Consider also the request timeout\n // Modern browser return readyState=4 and status=0 if too much time passes before the server response.\n result = { 'status': 408, 'message': 'XMLHttpRequest Exception: unkown error' };\n XHRData = result;\n // update toolbar\n if ( gina && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar && XHRData ) {\n try {\n // don't refresh for html datas\n if ( envIsDev && typeof(XHRData) != 'undefined' && /\\/html/.test(contentType) ) {\n window.ginaToolbar.update(\"data-xhr\", XHRData);\n }\n\n } catch (err) {\n throw err\n }\n }\n \n // intercept upload\n if ( /^gina\\-upload/i.test(id) ) {\n result.message = 'XMLHttpRequest Exception: trying to render an unknwon file.'\n onUpload(gina, $target, 'error', id, result);\n }\n triggerEvent(gina, $target, 'error.' + id, result);\n \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hform', result);\n \n return;\n }*/\n } \n \n };\n\n // catching request progress\n xhr.onprogress = function(event) {\n \n var percentComplete = '0';\n if (event.lengthComputable) {\n percentComplete = event.loaded / event.total;\n percentComplete = parseInt(percentComplete * 100);\n\n }\n\n //var percentComplete = (event.position / event.totalSize)*100;\n var result = {\n 'status': 100,\n 'progress': percentComplete\n };\n \n //console.debug('xhr progress ', percentComplete);\n\n $form.eventData.onprogress = result;\n\n triggerEvent(gina, $target, 'progress.' + id, result)\n };\n\n // catching timeout\n xhr.ontimeout = function (event) {\n result = {\n 'status': 408,\n 'error': 'Request Timeout'\n };\n\n $form.eventData.ontimeout = result;\n\n // intercept upload\n if ( /^gina\\-upload/i.test(id) )\n onUpload(gina, $target, 'error', id, result);\n \n triggerEvent(gina, $target, 'error.' + id, result);\n \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hform', result);\n };\n\n\n // sending\n if (!data)\n data = event.detail.data;\n\n if (data) {\n\n var hasBinaries = false;\n \n if ( typeof(data) == 'object' ) {\n\n var binaries = []\n , b = 0\n , newData = {};\n\n try {\n if ( !(data instanceof FormData) ) {\n data = JSON.stringify(data)\n } else {\n var uploadGroup = event.currentTarget.getAttribute('data-gina-form-upload-group') || 'untagged';\n for (var [key, value] of data.entries()) {\n // file upload case\n if (value instanceof File) {\n if (!hasBinaries)\n hasBinaries = true;\n \n binaries[b] = {\n key: key,\n group: uploadGroup, // `untagged` by default\n file: value,\n bin: ''\n };\n \n ++b;\n } else {\n newData[key] = value\n }\n \n }\n }\n\n \n if (hasBinaries && binaries.length > 0) {\n\n // We need a separator to define each part of the request\n var boundary = '--ginaWKBoundary' + uuid.v4().replace(/\\-/g, ''); \n \n \n return processFiles(binaries, boundary, '', 0, function onComplete(err, data, done) {\n \n if (err) {\n //throw err\n // intercept upload\n if ( /^gina\\-upload/i.test(id) )\n onUpload(gina, $target, 'error', id, err);\n \n triggerEvent(gina, $target, 'error.' + id, err);\n \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hform', err);\n } else {\n\n if (done) {\n xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);\n xhr.send(data);\n \n $form.sent = true;\n if ( envIsDev && isGFFCtx && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar ) {\n // update toolbar\n if (!gina.forms.sent)\n gina.forms.sent = {};\n \n var objCallback = {\n id : id,\n sent : data\n //sent : ( typeof(data) == 'string' ) ? JSON.parse(data) : data\n };\n \n window.ginaToolbar.update('forms', objCallback);\n }\n }\n\n done = false;\n\n return false;\n } \n });\n \n } else if ( typeof(newData) != 'undefined' && newData.count() > 0 ) { // without file\n data = JSON.stringify(newData)\n }\n \n \n } catch (err) {\n // intercept upload\n if ( /^gina\\-upload/i.test(id) )\n onUpload(gina, $target, 'error', id, err);\n \n triggerEvent(gina, $target, 'error.' + id, err);\n \n if (hFormIsRequired)\n triggerEvent(gina, $target, 'error.' + id + '.hform', err);\n }\n }\n //console.debug('sending -> ', data);\n if (!hasBinaries) {\n if (typeof (enctype) != 'undefined' && enctype != null && enctype != '') {\n xhr.setRequestHeader('Content-Type', enctype);\n }\n xhr.send(data)\n }\n\n } else {\n\n if ( typeof(enctype) != 'undefined' && enctype != null && enctype != ''){\n xhr.setRequestHeader('Content-Type', enctype);\n }\n xhr.send()\n }\n\n $form.sent = true;\n if ( envIsDev && isGFFCtx && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar ) {\n // update toolbar\n if (!gina.forms.sent)\n gina.forms.sent = {};\n\n var objCallback = {\n id : id,\n sent : ( typeof(data) == 'string' ) ? JSON.parse(data) : data\n };\n\n window.ginaToolbar.update('forms', objCallback);\n }\n }\n }\n \n var onUpload = function(gina, $target, status, id, data) {\n \n var uploadProperties = $target.uploadProperties || null;\n // FYI\n // { \n // id : String,\n // $form : $Object,\n // mandatoryFields : Array,\n // uploadFields : ObjectList\n // hasPreviewContainer : Boolean,\n // previewContainer : $Object\n // }\n \n if ( !uploadProperties )\n throw new Error('No uploadProperties found !!');\n // parent form\n // var $mainForm = uploadProperties.$form;\n var $uploadTriger = document.getElementById(uploadProperties.uploadTriggerId);\n var searchArr = null\n , name = null\n , $previewContainer = null\n , files = data.files || []\n , $error = null\n ;\n // reset previewContainer\n if ( uploadProperties.hasPreviewContainer ) { \n $previewContainer = document.getElementById(uploadProperties.previewContainer.id);\n if ($previewContainer)\n $previewContainer.innerHTML = '';\n }\n \n if (uploadProperties.errorField) {\n $error = document.getElementById(uploadProperties.errorField)\n }\n \n \n //reset errors\n if ($error)\n $error.style.display = 'none';\n \n if ($error && status != 'success') { // handle errors first\n // console.error('[ mainUploadError ] ', status, data)\n var errMsg = data.message || data.error; \n \n $error.innerHTML = '<p>'+ errMsg +'</p>';\n fadeIn($error);\n } else if(!$error && status != 'success') {\n throw new Error(errMsg)\n } else {\n \n var fieldsObjectList = null\n , $li = null\n , maxWidth = null\n , ratio = null\n ;\n for (var f = 0, fLen = files.length; f<fLen; ++f) {\n \n // creating reset link\n let resetLinkId = $previewContainer.id.replace(/\\-preview/, '-'+f+'-reset-trigger');\n let resetLinkNeedToBeAdded = false;\n let $resetLink = document.getElementById(resetLinkId);\n let defaultClassNameArr = ['reset','js-upload-reset'];\n if (!$resetLink) {\n resetLinkNeedToBeAdded = true;\n $resetLink = document.createElement('A');\n $resetLink.href = '#';\n $resetLink.innerHTML = $uploadTriger.getAttribute('data-gina-form-upload-reset-label') || 'Reset';\n $resetLink.className = defaultClassNameArr.join(' '); \n $resetLink.id = resetLinkId;\n } else {\n if ( /a/i.test($resetLink.tagName) ) {\n $resetLink.href = '#';\n }\n if ( !$resetLink.innerHTML || $resetLink.innerHTML == '' ) {\n $resetLink.innerHTML = $uploadTriger.getAttribute('data-gina-form-upload-reset-label') || 'Reset';\n }\n if ( typeof($resetLink.className) == 'undefined' ) {\n $resetLink.className = \"\";\n }\n let classNameArr = merge($resetLink.className.split(/\\s+/g), defaultClassNameArr);\n $resetLink.className = classNameArr.join(' ');\n } \n $resetLink.style.display = 'none';\n \n // image preview\n if ( typeof(files[f].preview) == 'undefined' \n && uploadProperties.hasPreviewContainer \n && /^image/.test(files[f].mime)\n && files[f].location != ''\n ) {\n let $img = document.createElement('IMG');\n $img.src = files[f].tmpUri;\n $img.style.display = 'none';\n $img.setAttribute('data-upload-original-filename', files[f].originalFilename);\n $img.setAttribute('data-upload-reset-link-id', $resetLink.id);\n \n // TODO - Remove this; we don't want it by default, the dev can force it by hand if needed\n // if (files[f].width) {\n // $img.width = files[f].width;\n // }\n // if (files[f].height) {\n // $img.height = files[f].height;\n // }\n \n maxWidth = $previewContainer.getAttribute('data-preview-max-width') || null;\n if ( $img.width && maxWidth && $img.width > maxWidth ) {\n ratio = $img.width / maxWidth;\n $img.width = maxWidth;\n $img.height = $img.height / ratio;\n } else if (!$img.width && maxWidth ) {\n $img.width = maxWidth\n }\n \n if ( /ul/i.test(uploadProperties.previewContainer.tagName) ) {\n $li = document.createElement('LI');\n $li.className = 'item';\n $li.appendChild($img);\n $previewContainer.appendChild($li); \n } else {\n $previewContainer.appendChild($img);\n }\n fadeIn($img);\n }\n // fill the fields to be saved ;) \n fieldsObjectList = uploadProperties.uploadFields[f];\n var $elIgnored = null;\n for (var key in fieldsObjectList) { \n // update field value\n if ( \n key == 'name' && fieldsObjectList[key].value != '' \n || !files[f][key]\n || key == 'preview' && typeof(files[f][key]) == 'undefined'\n || /(height|width)/i.test(key) && !/^image/.test(files[f].mime)\n ) {\n if ( /(preview|height|width)/i.test(key) ) {\n $elIgnored = document.getElementById(fieldsObjectList[key].id);\n if ( $elIgnored )\n $elIgnored.parentNode.removeChild($elIgnored);\n }\n continue;\n }\n //fieldsObjectList[key].value = (/object/i.test(typeof(files[f][key])) ) ? JSON.stringify( files[f][key] ) : files[f][key];\n fieldsObjectList[key].value = files[f][key];\n // update submited $fields ??\n \n // handle preview\n if ( key == 'preview' ) {\n \n for (var previewKey in files[f][key]) { \n if ( typeof(files[f][key][previewKey]) != 'undefined' && typeof(fieldsObjectList[key][previewKey]) != 'undefined' ) {\n fieldsObjectList[key][previewKey].value = files[f][key][previewKey];\n }\n \n // with preview\n if ( previewKey == 'tmpUri' && uploadProperties.hasPreviewContainer ) { \n \n // // creating reset link\n // let resetLinkId = $previewContainer.id.replace(/\\-preview/, '-'+f+'-reset-trigger');\n // let resetLinkNeedToBeAdded = false;\n // let $resetLink = document.getElementById(resetLinkId);\n // let defaultClassNameArr = ['reset','js-upload-reset'];\n // if (!$resetLink) {\n // resetLinkNeedToBeAdded = true;\n // $resetLink = document.createElement('A');\n // $resetLink.href = '#';\n // $resetLink.innerHTML = $uploadTriger.getAttribute('data-gina-form-upload-reset-label') || 'Reset';\n // $resetLink.className = defaultClassNameArr.join(' '); \n // $resetLink.id = resetLinkId;\n // } else {\n // if ( /a/i.test($resetLink.tagName) ) {\n // $resetLink.href = '#';\n // }\n // if ( !$resetLink.innerHTML || $resetLink.innerHTML == '' ) {\n // $resetLink.innerHTML = $uploadTriger.getAttribute('data-gina-form-upload-reset-label') || 'Reset';\n // }\n // if ( typeof($resetLink.className) == 'undefined' ) {\n // $resetLink.className = \"\";\n // }\n // let classNameArr = merge($resetLink.className.split(/\\s+/g), defaultClassNameArr);\n // $resetLink.className = classNameArr.join(' ');\n // } \n // $resetLink.style.display = 'none';\n \n \n // creating IMG tag\n let $img = document.createElement('IMG');\n $img.src = files[f][key].tmpUri;\n $img.style.display = 'none';\n // retrieve img `originalFilename` (not the preview img[key] `originalFilename`)\n // these 2 metadatas will be used to remove files from the server\n $img.setAttribute('data-upload-original-filename', files[f].originalFilename);\n $img.setAttribute('data-upload-preview-original-filename', files[f][key].originalFilename);\n // in order to retrieve and remove reset link\n $img.setAttribute('data-upload-reset-link-id', $resetLink.id);\n \n maxWidth = $previewContainer.getAttribute('data-preview-max-width') || null;\n if ( maxWidth ) {\n $img.width = maxWidth\n }\n \n if ( /ul/i.test(uploadProperties.previewContainer.tagName) ) {\n $li = document.createElement('LI');\n $li.className = 'item';\n $li.appendChild($img);\n // if (resetLinkNeedToBeAdded)\n // $li.appendChild($resetLink);\n \n $previewContainer.appendChild($li); \n } else {\n $previewContainer.appendChild($img);\n // if (resetLinkNeedToBeAdded)\n // $previewContainer.appendChild($resetLink);\n }\n fadeIn($img);\n // // bind reset trigger\n // bindUploadResetOrDeleteTrigger('reset', $uploadTriger, f);\n // fadeIn($resetLink);\n }\n } \n } \n } // EO for \n \n if (uploadProperties.hasPreviewContainer) {\n if ( /ul/i.test(uploadProperties.previewContainer.tagName) ) {\n $li = document.createElement('LI');\n $li.className = 'item';\n if (resetLinkNeedToBeAdded)\n $li.appendChild($resetLink); \n $previewContainer.appendChild($li); \n } else { \n if (resetLinkNeedToBeAdded)\n $previewContainer.appendChild($resetLink);\n }\n }\n // bind reset trigger\n bindUploadResetOrDeleteTrigger('reset', $uploadTriger, f);\n fadeIn($resetLink);\n } // EO for f\n }\n }\n \n /**\n * onUploadResetOrDelete\n * \n * @param {object} $uploadTrigger \n * @param {string} bindingType - `reset` or `delete`\n * @returns \n */\n var onUploadResetOrDelete = function($uploadTrigger, bindingType) {\n console.debug(bindingType + ' input files');\n var isOnResetMode = ( /reset/i.test(bindingType) ) ? true : false\n , uploadPreviewId = $uploadTrigger.id +'-preview'\n , $uploadPreview = document.getElementById(uploadPreviewId);\n \n var childNodeFile = null\n , childNodeFilePreview = null\n , childNodes = $uploadPreview.childNodes\n , $resetLink = null\n , files = $uploadTrigger.customFiles\n , filesToBeRemoved = []\n ;\n \n for (let i = 0, len = childNodes.length; i < len; i++) {\n // only look for IMG tags\n if ( /img/i.test(childNodes[i].tagName) ) {\n if (isOnResetMode) {\n childNodeFile = childNodes[i].getAttribute('data-upload-original-filename');\n filesToBeRemoved.push(childNodeFile);\n childNodeFilePreview = childNodes[i].getAttribute('data-upload-preview-original-filename');\n if (childNodeFilePreview) {\n filesToBeRemoved.push(childNodeFilePreview);\n }\n } else {\n let file = childNodes[i].src.substr(childNodes[i].src.lastIndexOf('/')+1);\n childNodeFile = file;\n filesToBeRemoved.push(childNodeFile);\n }\n \n // remove file from input.files\n for (let f = 0, fLen = files.length; f < fLen; f++) { \n if (files[f].name == childNodeFile) { \n // get resetLink element\n if (isOnResetMode) {\n $resetLink = document.getElementById( childNodes[i].getAttribute('data-upload-'+ bindingType +'-link-id') );\n } else {\n $resetLink = document.getElementById( files[f].deleteLinkId );\n }\n \n // hide reset or delete link & image\n $resetLink.style.display = 'none';\n childNodes[i].style.display = 'none';\n \n // remove file from input.files \n files.splice(f, 1);\n // Since `$uploadTrigger.files` isFrozen & isSealed\n $uploadTrigger.customFiles = files;\n if (isOnResetMode) {\n $uploadTrigger.value = files.join(', C:\\\\fakepath\\\\');\n } \n \n // update form files for validation & submit/send\n let re = new RegExp('^'+($uploadTrigger.name+'['+f+']').replace(/\\-|\\[|\\]|\\./g, '\\\\$&'));\n for ( let d = 0, dLen = $uploadTrigger.form.length; d < dLen; d++) {\n // data-gina-form-upload-is-locked\n // this exception prevent `tagged datas` to be deleted on image delete\n let isLocked = $uploadTrigger.form[d].dataset.ginaFormUploadIsLocked || false;\n if ( re.test($uploadTrigger.form[d].name) && !/true/i.test(isLocked) ) {\n $uploadTrigger.form[d].remove();\n dLen--;\n d--;\n //update toolbar\n if (gina && envIsDev && isGFFCtx && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar ) { \n try {\n // update toolbar\n window.ginaToolbar.update('data-xhr', {files: files}); \n } catch (err) {\n throw err\n }\n }\n }\n }\n // remove file from the server - filesToBeRemoved \n let url = $uploadTrigger.getAttribute('data-gina-form-upload-'+ bindingType +'-action');\n if ( !url || typeof(url) == 'undefined' || url == '' || /404/.test(url) ) {\n throw new Error('input file `'+ $uploadTrigger.id +'` error: `data-gina-form-upload-'+bindingType+'-action` is required. You need to provide a valide url.');\n }\n let method = $uploadTrigger.getAttribute('data-gina-form-upload-'+ bindingType +'-method');\n if ( !method || typeof(method) == 'undefined' || method == '') { \n if (isOnResetMode) {\n method = 'POST';\n } else {\n method = (filesToBeRemoved.length > 1) ? 'POST': 'DELETE';\n console.warn('`data-gina-form-upload-'+ bindingType +'-method` was not defined. Switching to `'+ method +'` by default.'); \n }\n } else {\n method = method.toUpperCase();\n }\n let isSynchrone = $uploadTrigger.getAttribute('data-gina-form-upload-'+ bindingType +'-is-synchrone');\n if ( /null/i.test(isSynchrone) || typeof(method) == 'undefined' || method == '' ) {\n isSynchrone = true;\n }\n \n let xhrOptions = {\n url: url,\n method: method,\n isSynchrone: isSynchrone,\n headers : {\n // to upload, use `multipart/form-data` for `enctype`\n 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n // cross domain is enabled by default, but you need to setup `Access-Control-Allow-Origin`\n 'X-Requested-With': 'XMLHttpRequest' // in case of cross domain origin\n }\n };\n let xhr = setupXhr(xhrOptions);\n //handleXhr(xhr);\n if ( /GET|DELETE/i.test(method) ) {\n xhr.send();\n } else {\n xhr.send(JSON.stringify({ files: filesToBeRemoved }));\n } \n \n // when there is no more files to preview, restore input file visibility\n // display upload input\n if ( /none/i.test(window.getComputedStyle($uploadTrigger).display) ) {\n // eg.: visibility could be delegated to a parent element such as label or a div \n if ( /none/i.test($uploadTrigger.parentElement.style.display) ) {\n $uploadTrigger.parentElement.style.display = 'block';\n return;\n }\n $uploadTrigger.style.display = 'block';\n }\n \n // remove reset link event\n removeListener(gina, $uploadResetTrigger, 'click', function onUploadResetTriggerEventRemoved() {\n // remove link & image - must be done last\n $resetLink.remove();\n childNodes[i].remove();\n }); \n len--;\n i--;\n break;\n }\n } // EO for\n }\n }\n } \n\n /**\n * Convert <Uint8Array|Uint16Array|Uint32Array> to <String>\n * @param {array} buffer\n * @param {number} [byteLength] e.g.: 8, 16 or 32\n * \n * @returns {string} stringBufffer\n */\n var ab2str = function(event, buf, byteLength) {\n\n var str = '';\n var ab = null;\n\n if ( typeof(byteLength) == 'undefined' ) {\n var byteLength = 8;\n }\n\n \n var bits = (byteLength / 8) \n\n\n switch (byteLength) {\n case 8:\n ab = new Uint8Array(buf);\n break;\n case 16:\n ab = new Uint16Array(buf);\n break;\n\n case 32:\n ab = new Uint32Array(buf);\n break;\n \n default:\n ab = new Uint8Array(buf); \n break; \n\n }\n\n var abLen = ab.length;\n var CHUNK_SIZE = Math.pow(2, 8) + bits;\n var offset = 0, len = null, subab = null;\n \n for (; offset < abLen; offset += CHUNK_SIZE) {\n len = Math.min(CHUNK_SIZE, abLen - offset);\n subab = ab.subarray(offset, offset + len);\n str += String.fromCharCode.apply(null, subab);\n }\n \n return str;\n }\n\n\n var processFiles = function(binaries, boundary, data, f, onComplete) {\n\n var reader = new FileReader();\n \n // progress\n // reader.addEventListener('progress', (e) => {\n // var percentComplete = '0';\n // if (e.lengthComputable) {\n // percentComplete = e.loaded / e.total;\n // percentComplete = parseInt(percentComplete * 100);\n\n // }\n\n // // var result = {\n // // 'status': 100,\n // // 'progress': percentComplete\n // // };\n \n // console.debug('progress', percentComplete);\n\n // //$form.eventData.onprogress = result;\n\n // //triggerEvent(gina, $target, 'progress.' + id, result)\n // });\n\n reader.addEventListener('load', function onReaderLoaded(e) {\n\n e.preventDefault();\n \n // var percentComplete = '0';\n // if (e.lengthComputable) {\n // percentComplete = e.loaded / e.total;\n // percentComplete = parseInt(percentComplete * 100);\n \n // console.debug('progress', percentComplete);\n // }\n \n\n try {\n \n var bin = ab2str(e, this.result);\n ; \n binaries[this.index].bin += bin;\n\n if (!binaries[this.index].file.type) {\n binaries[this.index].file.type = 'application/octet-stream'\n }\n\n } catch (err) {\n return onComplete(err, null, true);\n }\n\n // Start a new part in our body's request\n data += \"--\" + boundary + \"\\r\\n\";\n\n // Describe it as form data\n data += 'Content-Disposition: form-data; '\n // Define the name of the form data\n + 'name=\"' + binaries[this.index].key + '\"; ' \n // Define the upload group\n + 'group=\"' + binaries[this.index].group + '\"; '\n // Provide the real name of the file\n + 'filename=\"' + binaries[this.index].file.name + '\"\\r\\n'\n // And the MIME type of the file\n + 'Content-Type: ' + binaries[this.index].file.type + '\\r\\n'\n // File length\n + 'Content-Length: ' + binaries[this.index].bin.length + '\\r\\n'\n // There's a blank line between the metadata and the data\n + '\\r\\n';\n\n // Append the binary data to our body's request\n data += binaries[this.index].bin + '\\r\\n';\n\n ++this.index;\n // is last file ?\n if (this.index == binaries.length) {\n // Once we are done, \"close\" the body's request\n data += \"--\" + boundary + \"--\";\n\n onComplete(false, data, true);\n\n } else { // process next file\n processFiles(binaries, boundary, data, this.index, onComplete)\n } \n }, false);\n\n reader.index = f;\n binaries[f].bin = '';\n\n reader.readAsArrayBuffer(binaries[f].file);\n //reader.readAsBinaryString(binaries[f].file);\n }\n\n \n var listenToXhrEvents = function($form) {\n \n //data-gina-form-event-on-submit-success\n var htmlSuccesEventCallback = $form.target.getAttribute('data-gina-form-event-on-submit-success') || null;\n if (htmlSuccesEventCallback != null) {\n\n if ( /\\((.*)\\)/.test(htmlSuccesEventCallback) ) {\n eval(htmlSuccesEventCallback)\n } else {\n $form.on('success.hform', window[htmlSuccesEventCallback])\n }\n }\n //data-gina-form-event-on-submit-error\n var htmlErrorEventCallback = $form.target.getAttribute('data-gina-form-event-on-submit-error') || null;\n if (htmlErrorEventCallback != null) {\n if ( /\\((.*)\\)/.test(htmlErrorEventCallback) ) {\n eval(htmlErrorEventCallback)\n } else {\n $form.on('error.hform', window[htmlErrorEventCallback])\n }\n } \n \n }\n \n\n var destroy = function(formId) {\n var $form = null, _id = formId;\n\n if ( !instance['$forms'] )\n throw new Error('`$forms` collection not found');\n\n\n if ( typeof(_id) == 'undefined') {\n if ( typeof(this.id) != 'undefined' && this.id != '' && this.id != null ) {\n _id = this.id\n } else {\n throw new Error('[ FormValidator::destroy(formId) ] `formId` is missing')\n }\n }\n\n if ( typeof(_id) == 'string') {\n _id = _id.replace(/\\#/, '')\n } else if ( typeof(_id) == 'object' && !Array.isArray(_id) ) { // weird exception\n var $target = _id.form;\n _id = $target.getAttribute('id') || 'form.'+uuid.v4();\n\n $target.setAttribute('id', _id);// just in case\n\n } else {\n throw new Error('[ FormValidator::destroy(formId) ] `formId` should be a `string`');\n }\n\n if ( typeof(instance['$forms'][_id]) != 'undefined' ) {\n $form = instance['$forms'][_id]\n } else if ( typeof(this.binded) != 'undefined' ) {\n $form = this;\n }\n\n if ($form) { \n\n addListener(gina, $form.target, 'destroy.' + _id, function(event) {\n\n cancelEvent(event);\n\n delete instance['$forms'][_id];\n removeListener(gina, event.currentTarget, event.type);\n removeListener(gina, event.currentTarget,'destroy');\n });\n \n // remove existing listeners\n $form = unbindForm($form);\n\n //triggerEvent(gina, instance['$forms'][_id].target, 'destroy.' + _id);\n triggerEvent(gina, $form.target, 'destroy.' + _id);\n\n } else {\n throw new Error('[ FormValidator::destroy(formId) ] `'+_id+'` not found');\n }\n\n }\n \n /**\n * cleanupInstanceRules\n * Will remove _case_ condition for empty rules\n * Used to remove empty `@import` after `checkForRulesImports` is called\n * \n */\n var cleanupInstanceRules = function() {\n var rule = ( typeof(arguments[0]) != 'undefined' ) ? arguments[0] : instance.rules; \n for (let r in rule) {\n let props = Object.getOwnPropertyNames(rule[r]);\n let p = 0, pLen = props.length;\n let hasCases = false, caseName = null;\n while (p < pLen) {\n if ( /^\\_case\\_/.test(props[p]) ) {\n hasCases = true;\n caseName = props[p];\n break;\n }\n p++\n }\n \n if ( !hasCases && typeof(rule[r]) == 'object') {\n cleanupInstanceRules(rule[r]);\n } \n \n if (caseName && Array.isArray(rule[r][caseName].conditions) && rule[r][caseName].conditions.length > 0) {\n let c = 0, len = rule[r][caseName].conditions.length;\n while (c < len) {\n if ( \n typeof(rule[r][caseName].conditions[c].rules) != 'undefined'\n && rule[r][caseName].conditions[c].rules.count() == 0 \n ) {\n rule[r][caseName].conditions.splice(c, 1);\n len--;\n c--;\n }\n c++;\n }\n } \n }\n }\n \n var checkForRulesImports = function (rules) {\n // check if rules has imports & replace\n var rulesStr = JSON.stringify(rules);\n var importedRules = rulesStr.match(/(\\\"@import\\s+[-_a-z A-Z 0-9/.]+\\\")/g) || [];\n // remove duplicate\n var filtered = [];\n for (let d = 0, dLen = importedRules.length; d < dLen; d++) {\n if (filtered.indexOf(importedRules[d]) < 0) {\n filtered.push(importedRules[d])\n }\n }\n importedRules = filtered;\n // TODO - complete mergingRules integration\n var mergingRules = rulesStr.match(/(\\\"_merging(.*))(\\s+\\:|\\:)(.*)(\\\",|\\\")/g)\n var isMerging = false;\n if (!instance.rules) {\n instance.rules = {}\n }\n if (importedRules && importedRules.length > 0) {\n var ruleArr = [], rule = {}, tmpRule = null, re = null;\n for (let r = 0, len = importedRules.length; r<len; ++r) {\n let importPath = importedRules[r].replace(/(@import\\s+|\\\"|\\')/g, '');\n ruleArr = importPath.replace(/(@import\\s+|\\\"|\\')/g, '').split(/\\s/g);\n // [\"\"@import client/form\", \"\"@import project26/edit demo/edit\"]\n //console.debug('ruleArr -> ', ruleArr, importedRules[r]);\n for (let i = 0, iLen = ruleArr.length; i<iLen; ++i) {\n tmpRule = ruleArr[i].replace(/\\//g, '.').replace(/\\-/g, '.');\n if ( typeof(instance.rules[ tmpRule ]) != 'undefined' ) {\n let rule = JSON.stringify(instance.rules[ tmpRule ]);\n let strRule = JSON.parse(rule);\n if ( typeof(strRule['_comment']) != 'undefined' ) {\n strRule['_comment'] += '\\n';\n } else {\n strRule['_comment'] = '';\n } \n strRule['_comment'] += 'Imported from `'+ importPath +'`';\n rule = JSON.stringify(strRule);\n rulesStr = rulesStr.replace(new RegExp(importedRules[r], 'g'), rule);\n // also need to replace in instance.rules\n instance.rules = JSON.parse(JSON.stringify(instance.rules).replace(new RegExp(importedRules[r], 'g'), '{}'));\n } else {\n console.warn('[formValidator:rules] <@import error> on `'+importedRules[r]+'`: rule `'+ruleArr[i]+'` not found. Ignoring.');\n continue;\n }\n }\n //console.debug('replacing ', importedRules[r]);\n re = new RegExp(importedRules[r]);\n isMerging = ( mergingRules && re.test(mergingRules.join()) ) ? true : false;\n if( isMerging ) {\n \n for (let m = 0, mLen = mergingRules.length; m < mLen; m++) {\n if ( re.test(mergingRules[m]) ) { \n let tmpStr = JSON.stringify(rule);\n tmpStr = tmpStr.substr(1, tmpStr.length-1);// removing ->{ ... }<-\n // is last ?\n if (m < mLen-1) {\n tmpStr += ','\n }\n try {\n rulesStr = rulesStr.replace( new RegExp(mergingRules[m], 'g'), tmpStr); \n // also need to replace in instance.rules\n instance.rules = JSON.parse(JSON.stringify(instance.rules).replace(new RegExp(mergingRules[m], 'g'), '{}'));\n } catch (error) {\n throw error\n } \n }\n }\n \n }\n rule = {}\n }\n\n rules = JSON.parse(rulesStr);\n parseRules(rules, '');\n \n try {\n cleanupInstanceRules();\n } catch (err) {\n console.error(err.stack);\n } \n }\n \n return rules;\n }\n\n var init = function (rules) {\n\n if (gina.hasValidator) {\n \n instance = merge(instance, gina.validator);\n instance.on('init', function(event) {\n instance.isReady = true;\n triggerEvent(gina, instance.target, 'ready.' + instance.id, instance)\n })\n } else {\n setupInstanceProto();\n instance.on('init', function onValidatorInit(event) {\n // parsing rules\n if ( typeof(rules) != 'undefined' && rules.count() ) {\n try { \n parseRules(rules, '');\n rules = checkForRulesImports(rules);\n // making copy\n if ( typeof(gina.forms.rules) == 'undefined' || !gina.forms.rules) {\n gina.forms.rules = rules\n } else { // inherits\n gina.forms.rules = merge(gina.forms.rules, rules, true);\n } \n // update instance.rules\n instance.rules = merge(instance.rules, JSON.clone(gina.forms.rules), true);\n } catch (err) {\n throw (err)\n }\n }\n \n if ( !local.rules.count() ) {\n local.rules = JSON.clone(instance.rules);\n }\n \n\n $validator.setOptions = setOptions;\n $validator.getFormById = getFormById;\n $validator.validateFormById = validateFormById;\n $validator.resetErrorsDisplay = resetErrorsDisplay;\n $validator.resetFields = resetFields;\n $validator.handleErrorsDisplay = handleErrorsDisplay;\n $validator.submit = submit;\n $validator.send = send;\n $validator.unbind = unbindForm;\n $validator.bind = bindForm;\n $validator.reBind = reBindForm;\n $validator.destroy = destroy;\n\n var id = null\n , $target = null\n , i = 0\n , $forms = []\n , $allForms = document.getElementsByTagName('form');\n\n\n // form has rule ?\n for (var f=0, len = $allForms.length; f<len; ++f) {\n // preparing prototype (need at least an ID for this)\n \n if ($allForms[f].getAttribute) {\n id = $allForms[f].getAttribute('id') || 'form.' + uuid.v4();\n if ( id !== $allForms[f].getAttribute('id') ) {\n $allForms[f].setAttribute('id', id)\n }\n } else {\n id = 'form.' + uuid.v4();\n $allForms[f].setAttribute('id', id)\n }\n\n //$allForms[f]['id'] = $validator.id = id;\n $validator.id = id;\n\n //if ( typeof($allForms[f].getAttribute('id')) != 'undefined' && $allForms[f].id != 'null' && $allForms[f].id != '') {\n\n $validator.target = $allForms[f];\n instance.$forms[id] = merge({}, $validator);\n\n var customRule = $allForms[f].getAttribute('data-gina-form-rule');\n\n if (customRule) {\n customRule = customRule.replace(/\\-|\\//g, '.');\n if ( typeof(rules) != 'undefined' ) {\n instance.$forms[id].rules[customRule] = instance.rules[customRule] = local.rules[customRule] = merge(JSON.clone( eval('gina.forms.rules.'+ customRule)), instance.rules[customRule]);\n }\n if ( typeof(local.rules[customRule]) == 'undefined' ) {\n throw new Error('['+id+'] no rule found with key: `'+customRule+'`. Please check if json is not malformed @ /forms/rules/' + customRule.replace(/\\./g, '/') +'.json'); \n }\n customRule = instance.rules[customRule];\n }\n\n // finding forms handled by rules\n if ( \n typeof(id) == 'string' \n && typeof(local.rules[id.replace(/\\-/g, '.')]) != 'undefined'\n ||\n typeof(customRule) == 'object'\n ) {\n $target = instance.$forms[id].target;\n if (customRule) {\n bindForm($target, customRule)\n } else {\n bindForm($target)\n }\n\n ++i\n }\n // TODO - remove this\n // migth not be needed anymore \n else {\n // weird exception when having in the form an element with name=\"id\"\n if ( typeof($allForms[f].id) == 'object' ) {\n delete instance.$forms[$allForms[f].id];\n\n var _id = $allForms[f].attributes.getNamedItem('id').nodeValue || 'form.'+uuid.v4();\n\n $allForms[f].setAttribute('id', _id);\n $allForms[f]['id'] = _id;\n\n $validator.target = $allForms[f];\n instance.$forms[_id] = merge({}, $validator);\n\n $target = instance.$forms[_id].target;\n if (customRule) {\n bindForm($target, customRule)\n } else {\n bindForm($target)\n }\n } else {\n\n $target = instance.$forms[$allForms[f].id].target;\n if (customRule) {\n bindForm($target, customRule)\n } else {\n bindForm($target)\n }\n }\n }\n //}\n\n }\n\n\n // setting up AJAX\n if (window.XMLHttpRequest) { // Mozilla, Safari, ...\n xhr = new XMLHttpRequest();\n } else if (window.ActiveXObject) { // IE\n try {\n xhr = new ActiveXObject(\"Msxml2.XMLHTTP\");\n } catch (e) {\n try {\n xhr = new ActiveXObject(\"Microsoft.XMLHTTP\");\n }\n catch (e) {}\n }\n }\n \n \n\n instance.isReady = true;\n gina.hasValidator = true;\n gina.validator = instance;\n triggerEvent(gina, instance.target, 'ready.' + instance.id, instance);\n });\n\n }\n\n instance.initialized = true;\n return instance\n }\n\n var initForm = function ($form) {\n\n var customRule = null\n , rules = ( typeof(local.rules.count() > 0 ) ) ? local.rules : instance.rules\n ;\n\n if ($form.getAttribute) {\n id = $form.getAttribute('id') || 'form.' + uuid.v4();\n if (id !== $form.getAttribute('id')) {\n $form.setAttribute('id', id)\n }\n } else {\n id = 'form.' + uuid.v4();\n $form.setAttribute('id', id)\n }\n\n $form.id = $validator.id = id;\n\n if (typeof ($form.id) != 'undefined' && $form.id != 'null' && $form.id != '') {\n\n $validator.target = $form;\n instance.$forms[$form.id] = merge({}, $validator);\n\n customRule = $form.getAttribute('data-gina-form-rule');\n\n if (customRule) {\n customRule = customRule.replace(/\\-|\\//g, '.');\n if ( typeof(rules[customRule]) == 'undefined') {\n customRule = null;\n throw new Error('[' + $form.id + '] no rule found with key: `' + customRule + '`');\n } else {\n customRule = rules[customRule]\n }\n }\n\n // finding forms handled by rules\n if (typeof ($form.id) == 'string' && typeof (rules[$form.id.replace(/\\-/g, '.')]) != 'undefined') {\n $target = instance.$forms[$form.id].target;\n if (customRule) {\n bindForm($target, customRule)\n } else {\n bindForm($target)\n }\n\n } else {\n // weird exception when having in the form an element with name=\"id\"\n if (typeof ($form.id) == 'object') {\n delete instance.$forms[$form.id];\n\n var _id = $form.attributes.getNamedItem('id').nodeValue || 'form.' + uuid.v4();\n\n $form.setAttribute('id', _id);\n $form.id = _id;\n\n $validator.target = $form;\n instance.$forms[_id] = merge({}, $validator);\n\n $target = instance.$forms[_id].target;\n if (customRule) {\n bindForm($target, customRule)\n } else {\n bindForm($target)\n }\n } else {\n\n $target = instance.$forms[$form.id].target;\n if (customRule) {\n bindForm($target, customRule)\n } else {\n bindForm($target)\n }\n }\n }\n } \n }\n\n /**\n * parseRules - Preparing rules paths\n *\n * @param {object} rules\n * @param {string} tmp - path\n * */\n var parseRules = function(rules, tmp) {\n var _r = null;\n for (var r in rules) {\n\n if ( typeof(rules[r]) == 'object' && typeof(instance.rules[tmp + r]) == 'undefined' ) {\n\n _r = r;\n if (/\\[|\\]/.test(r) ) { // must be a real path\n _r = r.replace(/\\[/g, '.').replace(/\\]/g, '');\n }\n \n instance.rules[tmp + _r] = rules[r];\n \n //delete instance.rules[r];\n parseRules(rules[r], tmp + _r +'.');\n }\n }\n }\n \n var getRuleObjByName = function(ruleName) {\n \n if ( typeof(local.rules[ruleName]) != 'undefined' ) {\n return local.rules[ruleName]\n }\n var rules = null;\n // just in case : many ways to access this method\n if ( typeof(instance.rules[ruleName]) == 'undefined' ) { \n parseRules(local.rules, '');\n local.rules = checkForRulesImports(local.rules);\n rules = local.rules[ruleName];\n if ( !rules ) {\n return {}\n }\n } else {\n rules = instance.rules[ruleName]\n }\n \n var ruleObj = JSON.clone(rules)\n , re = new RegExp('^'+ruleName)\n , propRe = new RegExp('^'+ruleName +'.')\n , propName = null\n ;\n \n var rulesFromPath = function(obj, keys, val, originalRuleObj, field, i, len) {\n if (!keys.length) { \n return\n }\n \n var _id = Object.getOwnPropertyNames(obj)[0];\n var _key = keys[0];\n var nextFieldName = null;\n if ( field == '') {\n field += _key;\n nextFieldName = field\n } else {\n nextFieldName = field + '['+ _key + ']'\n }\n \n if ( keys.length == 1) {\n // obj[ _key ] = ( \n // typeof(obj[ _key ]) == 'undefined' \n // && typeof(val) == 'object' \n // && Array.isArray(val)\n // ) ? [] : {} ;\n \n obj[ _id ] = merge(obj[ _id ], val, true); \n \n // if ( \n // typeof(originalRuleObj[nextFieldName]) != 'undefined' \n // //&& typeof(originalRuleObj[nextFieldName][_key]) != 'undefined' \n // ) {\n \n // originalRuleObj[nextFieldName] = val//merge(originalRuleObj[nextFieldName], val, true);\n // //if ( typeof(originalRuleObj[nextFieldName][_key]) != 'undefined' ) {\n // // originalRuleObj[nextFieldName][_key] = val\n // //}// else {\n // // originalRuleObj[nextFieldName][_key] = merge(originalRuleObj[nextFieldName][_key], val, true);\n // //}\n \n \n // } else if ( \n // typeof(originalRuleObj[field]) != 'undefined' \n // //&& typeof(originalRuleObj[field][_key]) != 'undefined'\n // ) {\n // originalRuleObj[field] = val\n // //originalRuleObj[field] = merge(originalRuleObj[field], val, true);\n // //if ( typeof(originalRuleObj[field][_key]) != 'undefined' ) { \n // // originalRuleObj[field][_key] = val//merge(originalRuleObj[field][_key], val, true);\n // //} //else {\n // // originalRuleObj[field] = merge(originalRuleObj[field], val, true);\n // //}\n \n // } else if ( typeof(originalRuleObj[_key]) != 'undefined' ) {\n // originalRuleObj[_key] = val\n // //originalRuleObj[_key] = merge(originalRuleObj[_key], val, true)\n // }\n \n \n } //else if ( typeof(originalRuleObj[nextFieldName]) != 'undefined' ) {\n // field = nextFieldName;\n //}\n \n keys.splice(0,1);\n if (nextFieldName == _id) {\n rulesFromPath(obj[ _id ], keys, val, originalRuleObj, nextFieldName, i, len)\n } else if ( typeof(obj[ _id ]) != 'undefined' ) {\n rulesFromPath(obj[ _id ], keys, val, originalRuleObj, nextFieldName, i, len)\n } else {\n rulesFromPath(obj, keys, val, originalRuleObj, field, i, len)\n }\n \n }\n \n for (var prop in instance.rules) {\n if ( prop != ruleName && re.test(prop) ) {\n \n propName = prop.replace(propRe, '');\n if ( /\\./.test(propName) ) {\n var keys = propName.split(/\\./g);\n rulesFromPath( ruleObj, keys, instance.rules[prop], ruleObj, '', 0, ruleObj.count()-1 )\n } \n }\n }\n //cache rules\n local.rules[ruleName] = ruleObj;\n return ruleObj\n }\n \n \n /**\n * makeObjectFromArgs\n * \n * \n * @param {string} root \n * @param {array} args \n * @param {object} obj \n * @param {number} len \n * @param {number} i \n * @param {string|object} value \n * @param {object} [rootObj]\n * \n * @returns {Object} rootObj\n */\n var makeObjectFromArgs = function(_root, args, _obj, len, i, _value, _rootObj) {\n \n // Closure Compiler requirements \n var _global = window['gina']['_global']; \n // js_externs\n _global.register({\n 'root' : _root || null,\n 'obj' : _obj || null,\n 'value' : _value || null,\n 'rootObj' : _rootObj || null\n });\n \n \n if (i == len) { // end\n eval(root +'=value');\n // backup result\n var result = JSON.clone(rootObj);\n // cleanup _global\n _global.unregister(['root', 'obj', 'rootObj', 'value', 'valueType']); \n return result\n }\n \n var key = args[i].replace(/^\\[|\\]$/g, '');\n \n // init root object\n if ( typeof(rootObj) == 'undefined' || !rootObj ) {\n rootObj = {};\n root = 'rootObj';\n \n root += (/^\\d+$/.test(key)) ? '['+ key + ']' : '[\"'+ key +'\"]';\n eval(root +'=obj'); \n } else {\n root += (/^\\d+$/.test(key)) ? '['+ key + ']' : '[\"'+ key +'\"]';\n }\n \n\n var nextKey = ( typeof(args[i + 1]) != 'undefined' ) ? args[i + 1].replace(/^\\[|\\]$/g, '') : null;\n var valueType = ( nextKey && parseInt(nextKey) == nextKey ) ? [] : {};\n _global.register({\n 'valueType' : valueType\n });\n if ( nextKey ) { \n eval(root +' = valueType');\n }\n \n if ( typeof(obj[key]) == 'undefined' ) {\n\n if (/^\\d+$/.test(nextKey)) { // collection index ?\n obj[key] = [];\n } else {\n obj[key] = {};\n }\n\n ++i;\n return makeObjectFromArgs(root, args, obj[key], len, i, value, rootObj);\n }\n \n ++i;\n return makeObjectFromArgs(root, args, obj[key], len, i, value, rootObj);\n }\n\n \n\n /**\n * makeObject - Preparing form data\n *\n * @param {object} obj - data\n * @param {string\\number\\boolean} value\n * @param {array} string\n * @param {number} len\n * @param {number} i\n *\n * */\n var makeObject = function (obj, value, args, len, i) {\n\n if (i >= len) {\n return false\n }\n\n var key = args[i].replace(/^\\[|\\]$/g, '');\n var nextKey = ( i < len-1 && typeof(args[i+1]) != 'undefined' ) ? args[i+1].replace(/^\\[|\\]$/g, '') : null;\n \n if ( typeof(obj[key]) == 'undefined' ) {\n if (nextKey && /^\\d+$/.test(nextKey)) {\n nextKey = parseInt(nextKey);\n obj[key] = []\n } else {\n obj[key] = {}\n }\n }\n\n var tmpObj = null;\n if ( Array.isArray(obj[key]) ) {\n //makeObjectFromArgs(obj[key], args, obj[key], args.length, 1, value);\n tmpObj = makeObjectFromArgs(key, args, obj[key], args.length, 1, value, null);\n obj[key] = merge(obj[key], tmpObj);\n makeObject(obj[key], value, args, len, i + 1);\n } else {\n if (i == len - 1) {\n obj[key] = value;\n }// else {\n makeObject(obj[key], value, args, len, i + 1)\n //}\n }\n }\n\n var formatData = function (data) {\n\n var args = null\n , obj = {}\n , key = null\n , fields = {}\n , altName = null\n ;\n\n var makeFields = function(fields, isObject, data, len, i) {\n if (i == len ) { // exit\n return fields\n }\n \n var name = (isObject) ? Object.keys(data)[i] : i;\n \n if ( /\\[(.*)\\]/.test(name) ) {\n // backup name key\n key = name;\n // properties\n args = name.match(/(\\[[-_\\[a-z 0-9]*\\]\\]|\\[[-_\\[a-z 0-9]*\\])/ig);\n // root\n name = name.match(/^[-_a-z 0-9]+\\[{0}/ig);\n //altName = name.replace(/.*\\[(.+)\\]$/, \"$1\");\n \n if ( typeof(fields[name]) == 'undefined' ) {\n fields[name] = ( Array.isArray(data[key]) ) ? [] : {};\n }\n // building object tree\n makeObject(obj, data[key], args, args.length, 0);\n \n fields[name] = merge(fields[name], obj);\n obj = {};\n \n } else { // normal case\n fields[name] = data[name];\n }\n name = null;\n altName = null;\n \n ++i;\n return makeFields(fields, isObject, data, len, i); \n }\n \n var len = ( typeof(data) == 'undefined' ) ? 0 : 1;// by default\n var isObject = false;\n if (Array.isArray(data)) {\n len = data.length;\n } else if ( typeof(data) == 'object' ) {\n len = data.count();\n isObject = true;\n } \n \n return makeFields(fields, isObject, data, len, 0);\n //return fields\n }\n \n var checkForDuplicateForm = function(id) {\n // check for duplicate form ids\n var $allForms = document.getElementsByTagName('form');\n var dID = null, duplicateFound = {};\n for (var d = 0, dLen = $allForms.length; d < dLen; ++d) {\n dID = $allForms[d].getAttribute('id') || null; \n if ( typeof(duplicateFound[dID]) == 'undefined' ) {\n duplicateFound[dID] = true;\n } else {\n if ( typeof(instance.$forms[dID]) != 'undefined' && !instance.$forms[dID].warned) {\n if (gina.popinIsBinded) {\n console.warn('Popin/Validator::bindForm($target, customRule): `'+ dID +'` is a duplicate form ID. If not fixed, this could lead to an undesirable behaviour.\\n Check inside your popin content'); \n } else {\n console.warn('Validator::bindForm($target, customRule): `'+ dID +'` is a duplicate form ID. If not fixed, this could lead to an undesirable behaviour.');\n }\n instance.$forms[dID].warned = true;\n } \n }\n }\n }\n \n \n var setObserver = function ($el) {\n var $formInstance = instance.$forms[$el.form.getAttribute('id')];\n var isDisabled = ( /^true$/i.test($el.disabled) ) ? true : false;\n if ( \n isDisabled\n && typeof($formInstance.rule) != 'undefined' \n && typeof($formInstance.rule[$el.name]) != 'undefined'\n && typeof($formInstance.rule[$el.name].exclude) != 'undefined'\n && /^false$/i.test($formInstance.rule[$el.name].exclude)\n ) {\n isDisabled = false;\n }\n // var allowedTypes = allowedLiveInputTypes.slice();\n if (!/^(radio|text|hidden|password|number|date|email)$/i.test($el.type) || isDisabled) {\n return;\n }\n \n // Credits to `Maciej Swist` @https://stackoverflow.com/questions/42427606/event-when-input-value-is-changed-by-javascript\n var descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, \"value\");\n var inputSetter = descriptor.set;\n\n //Then modify the \"setter\" of the value to notify when the value is changed:\n descriptor.set = function(val) {\n \n //changing to native setter to prevent the loop while setting the value\n Object.defineProperty(this, 'value', {set:inputSetter});\n \n var _evt = 'change.' + this.id;\n if ( val === this.value && val === this.defaultValue) {\n Object.defineProperty(this, 'value', descriptor);\n return;\n }\n if ( val === this.value) {\n //changing back to custom setter\n Object.defineProperty(this, 'value', descriptor);\n return;\n }\n \n this.value = val;\n // if (document.getElementById(this.id).value !== this.value) {\n // document.getElementById(this.id).value = this.value;\n // }\n\n //Custom code triggered when $el.value is set\n console.debug('Value set: '+val);\n \n if ( typeof(gina.events[_evt]) != 'undefined' ) {\n console.debug('trigger event on: ', this.name, _evt);\n triggerEvent(gina, this, _evt, val);\n }\n //changing back to custom setter\n Object.defineProperty(this, 'value', descriptor);\n }\n \n //Last add the new \"value\" descriptor to the $el element\n Object.defineProperty($el, 'value', descriptor);\n }\n \n var addLiveForInput = function($form, $el, liveCheckTimer, isOtherTagAllowed) {\n \n if (typeof(isOtherTagAllowed) == 'undefined' ) {\n isOtherTagAllowed = false;\n }\n var rules = $form.rules;\n var $formInstance = instance.$forms[$el.form.getAttribute('id')];\n var isDisabled = ( /^true$/i.test($el.disabled) ) ? true : false;\n if ( \n isDisabled\n && typeof($formInstance.rule) != 'undefined' \n && typeof($formInstance.rule[$el.name]) != 'undefined'\n && typeof($formInstance.rule[$el.name].exclude) != 'undefined'\n && /^false$/i.test($formInstance.rule[$el.name].exclude)\n ) {\n isDisabled = false;\n }\n // allowedLiveInputTypes\n if ( /^(radio|checkbox|text|hidden|password|number|date|email)$/i.test($el.type) && !isDisabled || isOtherTagAllowed && !isDisabled ) {\n var field = $el.name;\n var localRule = rules[field] || null;\n if ( !localRule ) {\n checkForRuleAlias(rules, $el);\n \n if ( typeof(rules[field]) == 'undefined' )\n return;\n }\n // data-gina-form-live-check-enabled\n // with local rule \n if ( $form.target.dataset.ginaFormLiveCheckEnabled && localRule) {\n \n var eventsList = [], _evt = null, _e = 0; \n if ( !/^(radio|checkbox)$/i.test($el.type) ) {\n addEventListener(gina, $el, 'focusout.'+$el.id, function(event) {\n event.preventDefault();\n clearTimeout(liveCheckTimer);\n });\n \n // BO Livecheck local events\n _evt = 'change.'+$el.id;\n if ( typeof(gina.events[_evt]) == 'undefined' ) {\n eventsList[_e] = _evt;\n ++_e;\n }\n \n _evt = 'keyup.'+$el.id;\n if ( typeof(gina.events[_evt]) == 'undefined' ) {\n eventsList[_e] = _evt;\n ++_e;\n }\n _evt = 'focusin.'+$el.id;\n if ( typeof(gina.events[_evt]) == 'undefined' ) {\n eventsList[_e] = _evt;\n ++_e;\n }\n _evt = 'focusout.'+$el.id;\n if ( typeof(gina.events[_evt]) == 'undefined' ) {\n eventsList[_e] = _evt;\n ++_e;\n }\n // EO Livecheck local events\n } else {\n if ( /^(radio|checkbox)$/i.test($el.type) ) {\n _evt = 'changed.'+$el.id;\n } else {\n _evt = 'change.'+$el.id;\n }\n \n if ( typeof(gina.events[_evt]) == 'undefined' ) {\n eventsList[_e] = _evt;\n ++_e;\n }\n }\n \n if (eventsList.length > 0) {\n var once = false;\n addListener(gina, $el, eventsList, function(event) { \n event.preventDefault(); \n clearTimeout(liveCheckTimer); \n if ( !once && /^changed\\./i.test(event.type) || !once && /^(radio|checkbox)$/i.test(event.target.type) ) {\n once = true;\n } else if (once && /^changed\\./i.test(event.type) || once && /^(radio|checkbox)$/i.test(event.target.type) ) { \n return false;\n }\n \n if ( \n typeof(instance.$forms[event.target.form.getAttribute('id')].isSubmitting) != 'undefined'\n && /true/i.test(instance.$forms[event.target.form.getAttribute('id')].isSubmitting)\n ) {\n return false;\n }\n \n var processEvent = function() {\n \n console.debug('processing: ' + event.target.name+ '/'+ event.target.id);\n \n // Do not validate `onChange` if `input value` === `orignal value`\n // Or else, you will get an endless loop\n if (\n // ignoring checkbox & radio because value for both have already changed\n !/^(radio|checkbox)$/i.test(event.target.type) \n && event.target.value === event.target.defaultValue\n && event.target.value != ''\n ) {\n //resetting error display\n var errors = instance.$forms[event.target.form.getAttribute('id')].errors;\n if (!errors || errors.count() == 0) {\n handleErrorsDisplay(event.target.form, {}, null, event.target.name);\n return cancelEvent(event);\n } else {\n handleErrorsDisplay(event.target.form, errors, null, event.target.name);\n }\n //return cancelEvent(event);\n }\n \n \n var localField = {}, $localField = {};\n localField[event.target.name] = event.target.value;\n $localField[event.target.name] = event.target;\n \n instance.$forms[event.target.form.getAttribute('id')].isValidating = true;\n validate(event.target, localField, $localField, $form.rules, function onLiveValidation(result){\n instance.$forms[event.target.form.getAttribute('id')].isValidating = false;\n //console.debug('validation on processEvent(...) ', result);\n \n var isFormValid = result.isValid();\n //console.debug('onSilentPreGlobalLiveValidation: '+ isFormValid, result);\n if (isFormValid) {\n //resetting error display\n handleErrorsDisplay(event.target.form, {}, result.data, event.target.name);\n } else { \n handleErrorsDisplay(event.target.form, result.error, result.data, event.target.name);\n }\n //updateSubmitTriggerState( event.target.form, isFormValid );\n // data-gina-form-required-before-submit\n //console.debug('====>', result.isValid(), result);\n \n // Global check required: on all fields\n var $gForm = event.target.form, gFields = null, $gFields = null, gRules = null;\n var gValidatorInfos = getFormValidationInfos($gForm, rules);\n gFields = gValidatorInfos.fields;\n $gFields = gValidatorInfos.$fields;\n var formId = $gForm.getAttribute('id');\n gRules = instance.$forms[formId].rules;\n // Don't be tempted to revome fields that has already been validated\n instance.$forms[formId].isValidating = true;\n validate($gForm, gFields, $gFields, gRules, function onSilentGlobalLiveValidation(gResult){\n instance.$forms[formId].isValidating = false;\n console.debug('['+ formId +'] onSilentGlobalLiveValidation: '+ gResult.isValid(), gResult);\n var isFormValid = gResult.isValid();\n if ( envIsDev && isGFFCtx && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar ) {\n // update toolbar\n if (!gina.forms.errors)\n gina.forms.errors = {};\n \n var objCallback = {\n id : formId,\n errors : gResult.error || {}\n };\n \n window.ginaToolbar.update('forms', objCallback);\n } \n \n \n updateSubmitTriggerState( $gForm, isFormValid);\n \n once = false;\n })\n \n });\n \n \n return;\n }\n \n // radio & checkbox only\n if ( \n /^changed\\./i.test(event.type) \n || \n /^change\\./i.test(event.type) \n && event.target.type == 'radio'\n ) {\n var i = 0;\n return function(once, i) {\n if (i > 0) return;\n ++i;\n return setTimeout(() => {\n console.debug(' changed .... '+$el.id);\n processEvent();\n }, 0); \n \n }(once, i)\n \n }\n // other inputs & textareas\n else if ( /^focusin\\./i.test(event.type) ) {\n if ( /\\-error/.test($el.parentNode.className) ) {\n console.debug('#1 you just focusin ....'+$el.id, $el.value);\n refreshWarning($el);\n }\n }\n else if ( /^focusout\\./i.test(event.type) ) {\n if ( /\\-warning/.test($el.parentNode.className) ) {\n console.debug('#1 you just focusout ....'+$el.id, $el.value); \n refreshWarning($el);\n // in case error context is changed by another task\n handleErrorsDisplay($el.form, instance.$forms[ $el.form.getAttribute('id') ].errors, null, $el.name);\n }\n }\n else if ( /^keyup\\./i.test(event.type) ) {\n $el.ginaFormValidatorTestedValue = $el.value;\n liveCheckTimer = setTimeout( function onLiveCheckTimer() {\n // do not trigger for copy/paste event\n if ( ['91', '17'].indexOf(''+event.keyCode) > -1 && keyboardMapping.count() == 0) {\n //console.debug('mapping ', keyboardMapping);\n return;\n }\n console.debug(' keyup ('+ event.keyCode +') .... '+$el.id, $el.value, ' VS ',$el.ginaFormValidatorTestedValue + '(old)');\n processEvent();\n }, 1000); \n } \n else if (/^change\\./i.test(event.type) && !/^(checkbox)$/i.test(event.target.type) ) {\n console.debug(' change .... '+$el.id);\n processEvent();\n } \n });\n }\n }\n }\n return;\n }\n \n \n \n var setSelectionRange = function($el, selectionStart, selectionEnd) {\n if ($el.setSelectionRange) {\n $el.focus();\n $el.setSelectionRange(selectionStart, selectionEnd);\n }\n else if ($el.createTextRange) {\n var range = $el.createTextRange();\n range.collapse(true);\n range.moveEnd ('character', selectionEnd );\n range.moveStart('character', selectionStart);\n range.select();\n }\n }\n /**\n * setCaretToPos\n * If called after change of `readonly`, use `$el.blur()` before the call\n * \n * @param {object} $el - HTMLElement\n * @param {number} pos \n */\n var setCaretToPos = function ($el, pos) {\n setSelectionRange($el, pos, pos);\n }\n \n var isElementVisible = function($el) {\n return ($el.offsetWidth > 0 || $el.offsetHeight > 0 || $el === document.activeElement) ? true : false;\n }\n \n var focusNextElement = function($el, isGoingBackward) {\n // Add all elements we want to include in our selection\n // Checkboxes and radios are just ignored: like for the default behavior\n var focussableElements = 'a:not([disabled]), button:not([disabled]), input[type=text]:not([disabled]), select:not([disabled]), [tabindex]:not([disabled]):not([tabindex=\"-1\"])';\n if (document.activeElement && document.activeElement.form) {\n var focussable = Array.prototype.filter.call(document.activeElement.form.querySelectorAll(focussableElements),\n function (element) {\n //Check for visibility while always include the current activeElement \n return element.offsetWidth > 0 || element.offsetHeight > 0 || element === document.activeElement\n });\n var index = focussable.indexOf(document.activeElement);\n if(index > -1) {\n var direcion = focussable[index + 1]; // By default, going forward\n if (isGoingBackward) {\n direcion = focussable[index - 1]\n }\n var nextElement = direcion || focussable[0];\n nextElement.focus();\n } \n }\n }\n /**\n * handleAutoComplete\n * This is a temporary fix to handle safari autocomplete/autosuggest\n * Will be removed when Safari honores autocomplete=\"off\" \n * @param {object} $el HTMLElement\n */\n var handleAutoComplete = function($el, liveCheckTimer) {\n $el.setAttribute('readonly', 'readonly');\n addListener(gina, $el, 'focusout.'+ $el.id, function(event) {\n event.preventDefault();\n clearTimeout(liveCheckTimer);\n \n var $_el = event.currentTarget;\n triggerEvent(gina, $_el, 'change.'+ $_el.id);\n $_el.setAttribute('readonly', 'readonly');\n });\n addListener(gina, $el, 'focusin.'+ $el.id, function(event) {\n event.preventDefault();\n event.currentTarget.removeAttribute('readonly'); \n \n var evtName = 'keydown.'+ event.currentTarget.id;\n // add once\n if ( typeof(gina.events[evtName]) == 'undefined' ) {\n addListener(gina, event.currentTarget, evtName, function(e) {\n e.preventDefault();\n clearTimeout(liveCheckTimer);\n \n var $_el = e.currentTarget; \n var str = e.currentTarget.value;\n var posStart = $_el.selectionStart, posEnd = $_el.selectionEnd;\n $_el.removeAttribute('readonly');\n //console.debug('pressed: '+ e.key+'('+ e.keyCode+')', ' S:'+posStart, ' E:'+posEnd, ' MAP: '+ JSON.stringify(keyboardMapping));\n switch (e.keyCode) {\n case 46: //Delete\n case 8: //Backspace\n if (posStart != posEnd) {\n $_el.value = str.substr(0, posStart) + str.substr(posEnd);\n if (posStart == 0) {\n $_el.value = str.substr(posEnd);\n }\n } else if (posStart == 0) {\n $_el.value = str.substring(posStart+1);\n } else {\n $_el.value = str.substr(0, posStart-1) + str.substr(posEnd);\n }\n \n e.currentTarget.setAttribute('readonly', 'readonly'); \n setTimeout(() => {\n $_el.removeAttribute('readonly'); \n setTimeout(() => {\n if (posStart != posEnd) {\n setCaretToPos($_el, posStart);\n } else if (posStart == 0) {\n setCaretToPos($_el, posStart);\n } else {\n setCaretToPos($_el, posStart-1);\n }\n }, 0)\n \n }, 0);\n break;\n case 9: // Tab\n if (keyboardMapping[16] && keyboardMapping[9]) {\n focusNextElement($_el, true);\n } else {\n focusNextElement($_el);\n } \n break;\n case 13: // Enter \n case 16: // Shift\n break;\n case 37: // ArrowLeft\n console.debug('moving left ', posStart-1);\n setCaretToPos($_el, posStart-1); \n break;\n case 39: // ArrowRight\n if (posStart+1 < str.length+1) {\n setCaretToPos($_el, posStart+1);\n } \n break;\n // Shortcuts\n case 17: //CTRL\n case 91: //CMD\n console.debug(\"CMD hit\");\n e.preventDefault();\n break;\n case 67: // to handle CMD+C (copy)\n if (\n keyboardMapping[67] && keyboardMapping[91] // mac osx\n ||\n keyboardMapping[67] && keyboardMapping[17] // windows\n ) {\n $_el.setSelectionRange(posStart, posEnd);\n document.execCommand(\"copy\");\n break;\n }\n case 86: // to handle CMD+V (paste)\n if (\n keyboardMapping[86] && keyboardMapping[91] // mac osx\n ||\n keyboardMapping[86] && keyboardMapping[17] // windows\n ) {\n if (posStart != posEnd) {\n $_el.value = $_el.value.replace(str.substring(posStart, posEnd), '');\n }\n setCaretToPos($_el, posStart);\n document.execCommand(\"paste\");\n break;\n }\n case 88: // to handle CMD+X (cut)\n if (\n keyboardMapping[88] && keyboardMapping[91] // mac osx\n ||\n keyboardMapping[88] && keyboardMapping[17] // windows\n ) {\n $_el.setSelectionRange(posStart, posEnd);\n document.execCommand(\"cut\");\n break;\n }\n case 90: // to handle CMD+Z (undo)\n if (\n keyboardMapping[90] && keyboardMapping[91] // mac osx\n ||\n keyboardMapping[90] && keyboardMapping[17] // windows\n ) {\n $_el.value = $_el.defaultValue;\n break;\n }\n default:\n // Replace selection\n if (posStart != posEnd) {\n $_el.value = str.substr(0, posStart) + e.key;\n if (posEnd-1 < str.length) {\n $_el.value += str.substring(posEnd)\n }\n } else if (posStart == 0) {\n $_el.value = e.key + str.substring(posStart);\n } else {\n $_el.value = str.substr(0, posStart) + e.key + str.substr(posEnd);\n }\n e.currentTarget.setAttribute('readonly', 'readonly');\n // Force restore last caret position\n setTimeout(() => {\n $_el.removeAttribute('readonly');\n setTimeout(() => {\n setCaretToPos($_el, posStart+1);\n }, 0);\n \n }, 0);\n break;\n } //EO Switch\n });\n }\n \n });\n }\n \n var registerForLiveChecking = function($form, $el) {\n // Filter supported elements\n if ( \n !/^(input|textarea)$/i.test($el.tagName)\n ||\n typeof(gina.events['registered.' + $el.id]) != 'undefined'\n ) {\n return\n }\n // Mutation obeserver - all but type == files\n if ( !/^file$/i.test($el.type) ) {\n setObserver($el);\n } \n var liveCheckTimer = null\n switch ($el.tagName.toLowerCase()) {\n \n case 'textarea':\n addLiveForInput($form, $el, liveCheckTimer, true);\n break;\n default:\n addLiveForInput($form, $el, liveCheckTimer);\n // Bypass Safari autocomplete\n var isAutoCompleteField = $el.getAttribute('autocomplete');\n if (\n /safari/i.test(navigator.userAgent)\n && isAutoCompleteField\n && /^(off|false)/i.test(isAutoCompleteField) \n ) {\n handleAutoComplete($el, liveCheckTimer)\n }\n break;\n }\n gina.events['registered.' + $el.id] = $el.id;\n }\n \n /**\n * bindUploadResetOrDeleteTrigger\n * \n * @param {string} bindingType - `reset`or `delete`\n * @param {object} $uploadTrigger - HTMLFormElement\n * @param {number} index\n * \n */\n var bindUploadResetOrDeleteTrigger = function(bindingType, $uploadTrigger, index) {\n \n // Binding upload reset or delete trigger\n // var $currentForm = $uploadTrigger.form;\n // for (let i = 0, len = $currentForm.length; )\n // trigger is by default you {input.id} + '-delete-trigger' \n // e.g.: <input type=\"file\" id=\"my-upload\" name=\"my-upload\">\n // => <a href=\"/path/to/tmpfile/delete-action\" id=\"my-upload-delete-trigger\">Remove</a>\n // But you can use atrtibute `data-gina-form-upload-delete-trigger` to override it \n var uploadResetOrDeleteTriggerId = $uploadTrigger.id + '-' +index+ '-'+bindingType+'-trigger';\n var $uploadResetOrDeleteTrigger = document.getElementById(uploadResetOrDeleteTriggerId); \n if (!$uploadResetOrDeleteTrigger) {\n uploadResetOrDeleteTriggerId = $uploadTrigger.getAttribute('data-gina-form-upload-'+ '-' +index+ +bindingType+'-trigger');\n $uploadResetOrDeleteTrigger = document.getElementById(uploadResetOrDeleteTriggerId);\n }\n \n if ( \n $uploadResetOrDeleteTrigger \n && typeof($uploadResetOrDeleteTrigger.isBinded) == 'undefined' \n || \n $uploadResetOrDeleteTrigger \n && typeof($uploadResetOrDeleteTrigger.isBinded) != 'undefined' \n && !/true/i.test($uploadResetOrDeleteTrigger.isBinded) \n ) { \n addListener(gina, $uploadResetOrDeleteTrigger, 'click', function onUploadResetOrDeleteTriggerClick(e) {\n e.preventDefault();\n \n onUploadResetOrDelete($uploadTrigger, bindingType);\n });\n $uploadResetOrDeleteTrigger.isBinded = true;\n } else {\n console.warn('[FormValidator::bindForm][upload]['+$uploadTrigger.id+'] : did not find `upload '+bindingType+' trigger`.\\nPlease, make sure that your delete element ID is `'+ uploadResetOrDeleteTriggerId +'-'+bindingType+'-trigger`, or add to your file input ('+ $uploadTrigger.id +') -> `data-gina-form-upload-'+bindingType+'-trigger=\"your-custom-id\"` definition.');\n }\n }\n \n var checkUploadUrlActions = function($el, $errorContainer) {\n \n var checkAction = function($el, action, $errorContainer) {\n var defaultRoute = null;\n switch (action) {\n case 'data-gina-form-upload-action':\n defaultRoute = 'upload-to-tmp-xml';\n break;\n case 'data-gina-form-upload-reset-action':\n defaultRoute = 'upload-delete-from-tmp-xml';\n break;\n }\n var uploadActionUrl = $el.getAttribute(action);\n if (!uploadActionUrl || uploadActionUrl == '' ) {\n if (!defaultRoute)\n console.warn('`'+ action +'` definition not found for `'+ $el.id + '`. Trying to get default route.');\n var additionalErrorDetails = null;\n try {\n if (defaultRoute)\n uploadActionUrl = routing.getRoute(defaultRoute);\n } catch (err) {\n additionalErrorDetails = err;\n }\n \n if (uploadActionUrl) {\n console.info('Ignore previous warnings regarding upload. I have found a default `'+action+'` route: `'+ defaultRoute +'@'+ uploadActionUrl.bundle +'`');\n $el.setAttribute('data-gina-form-upload-action', uploadActionUrl.toUrl());\n } else {\n var errMsg = '`'+ action +'` needs to be defined to proceed for your `input[type=file]` with ID `'+ $el.id +'`\\n'+ additionalErrorDetails +'\\n';\n if ($errorContainer) {\n $errorContainer.innerHTML += errMsg.replace(/(\\n|\\r)/g, '<br>');\n }\n console.error(errMsg);\n } \n }\n }\n // checking upload-action\n checkAction($el, 'data-gina-form-upload-action', $errorContainer);\n // checking upload-reset-action\n checkAction($el, 'data-gina-form-upload-reset-action', $errorContainer);\n // checking upload-delete-action\n checkAction($el, 'data-gina-form-upload-delete-action', $errorContainer);\n }\n \n /**\n * reBindForm - This is a WIP\n * \n * @param {object} HTMLElement\n * @param {object} rules\n * @returns {object} formValidatorInstance\n */\n var reBindForm = function($target, rules, cb) {\n // Unbind form\n var formInstance = unbindForm($target);\n // reset errors\n //resetErrorsDisplay(formInstance.id); \n // Bind\n bindForm(formInstance.target, rules);\n \n if ( cb ) {\n return cb(formInstance); \n }\n return formInstance;\n }\n \n var unbindForm = function($target) {\n var $form = null\n , _id = null\n ;\n\n try {\n if ( $target.getAttribute && $target.getAttribute('id') ) {\n _id = $target.getAttribute('id');\n if ( typeof(instance.$forms[_id]) != 'undefined')\n $form = instance.$forms[_id];\n else\n throw new Error('form instance `'+ _id +'` not found');\n\n } else if ( typeof($target.target) != 'undefined' ) {\n $form = $target;\n _id = $form.id;\n } else {\n throw new Error('Validator::unbindForm($target): `$target` must be a DOM element\\n'+err.stack )\n }\n } catch(err) {\n throw new Error('Validator::unbindForm($target) could not unbind form `'+ $target +'`\\n'+err.stack )\n }\n \n // No need to unbind if not binded\n if ( typeof($form) != 'undefined' && !$form.binded) {\n return $form\n }\n \n // form events\n removeListener(gina, $form, 'success.' + _id);\n removeListener(gina, $form, 'error.' + _id);\n\n if ($form.target.getAttribute('data-gina-form-event-on-submit-success'))\n removeListener(gina, $form, 'success.' + _id + '.hform');\n \n if ($form.target.getAttribute('data-gina-form-event-on-submit-error'))\n removeListener(gina, $form, 'error.' + _id + '.hform');\n\n removeListener(gina, $form, 'validate.' + _id);\n removeListener(gina, $form, 'validated.' + _id);\n removeListener(gina, $form, 'submit.' + _id);\n removeListener(gina, $form, 'reset.' + _id);\n \n \n\n // binded elements\n var $el = null\n //, evt = null\n , $els = []\n , $elTMP = [];\n\n // submit buttons\n $elTMP = $form.target.getElementsByTagName('button');\n if ( $elTMP.length > 0 ) {\n for(let i = 0, len = $elTMP.length; i < len; ++i) {\n // if button is != type=\"submit\", you will need to provide : data-gina-form-submit\n // TODO - On button binding, you can then provide data-gina-form-action & data-gina-form-method\n $els.push($elTMP[i])\n }\n }\n\n // submit links\n $elTMP = $form.target.getElementsByTagName('a');\n if ( $elTMP.length > 0 ) {\n for(let i = 0, len = $elTMP.length; i < len; ++i) {\n $els.push($elTMP[i])\n }\n }\n\n // checkbox, radio, file, text, number, hidden, date .. ALL BUT hidden\n $elTMP = $form.target.getElementsByTagName('input');\n if ( $elTMP.length > 0 ) {\n for (let i = 0, len = $elTMP.length; i < len; ++i) {\n \n if ( !/^(hidden)$/i.test($elTMP[i].type) )\n $els.push( $elTMP[i] );\n \n \n if (/^(file)$/i.test($elTMP[i].type)) {\n // special case\n // vForm has to be handle here, it does not exist in the document context\n let vFormId = $elTMP[i].getAttribute('data-gina-form-virtual');\n if ( vFormId ) {\n let $vForm = getFormById(vFormId).target;\n if ($vForm) {\n $els.push( $vForm );\n // `events` is defined on top of this file\n // It is the list of allowed events\n for (let e = 0, eLen = events.length; e < eLen; e++) {\n let evt = events[e];\n if ( typeof(gina.events[ evt +'.'+ vFormId + '.hform' ]) != 'undefined' && gina.events[ evt +'.'+ vFormId + '.hform' ] == vFormId ) { \n removeListener(gina, $vForm, evt +'.'+ vFormId + '.hform')\n } \n } \n }\n }\n } else { // other types\n // `events` is defined on top of this file\n // It is the list of allowed events\n for (let e = 0, eLen = events.length; e < eLen; e++) {\n let evt = events[e] +'.'+ $elTMP[i].id;\n if ( typeof(gina.events[ evt ]) != 'undefined' && gina.events[ evt ] == $elTMP[i].id ) { \n removeListener(gina, $elTMP[i], evt);\n }\n evt = events[e];\n if ( typeof(gina.events[ evt ]) != 'undefined' && gina.events[ evt ] == $elTMP[i].id ) { \n removeListener(gina, $elTMP[i], evt);\n }\n evt = $elTMP[i].id;\n if ( typeof(gina.events[ evt ]) != 'undefined' && gina.events[ evt ] == $elTMP[i].id ) { \n removeListener(gina, $elTMP[i], evt);\n }\n }\n }\n }\n }\n \n // textarea\n $elTMP = $form.target.getElementsByTagName('textarea');\n if ( $elTMP.length > 0 ) {\n for(let i = 0, len = $elTMP.length; i < len; ++i) {\n $els.push( $elTMP[i] )\n }\n }\n \n \n // forms inside main form\n $elTMP = $form.target.getElementsByTagName('form');\n if ( $elTMP.length > 0 ) {\n for(let i = 0, len = $elTMP.length; i < len; ++i) {\n $els.push( $elTMP[i] )\n }\n }\n // main form\n $els.push( $form.target );\n for (let i = 0, len = $els.length; i < len; ++i) {\n\n $el = $els[i];\n let eId = $el.getAttribute('id');\n for (let e = 0, eLen = events.length; e < eLen; e++) {\n let evt = events[e];\n let eventName = evt; \n // remove proxy\n // if ( typeof(gina.events[ evt ]) != 'undefined' ) { \n // removeListener(gina, $el, evt);\n // } \n \n if ( typeof(gina.events[ eventName ]) != 'undefined' && gina.events[ eventName ] == eId ) { \n removeListener(gina, $el, eventName);\n }\n \n // eventName = evt +'._case_'+ $el.name;\n // if ( typeof(gina.events[ eventName ]) != 'undefined') { \n // removeListener(gina, $el, eventName);\n // } \n \n eventName = eId;\n if ( typeof(gina.events[ eventName ]) != 'undefined' && gina.events[ eventName ] == eId ) { \n removeListener(gina, $el, eventName);\n }\n \n eventName = evt +'.'+ eId;\n if ( typeof(gina.events[ eventName ]) != 'undefined' && gina.events[ eventName ] == eId ) { \n removeListener(gina, $el, eventName);\n }\n \n eventName = evt +'.'+ eId;\n if ( typeof(gina.events[ eventName ]) != 'undefined' && gina.events[ eventName ] == eventName ) { \n removeListener(gina, $el, eventName);\n }\n \n eventName = evt +'.'+ eId + '.hform';\n if ( typeof(gina.events[ eventName ]) != 'undefined' && gina.events[ eventName ] == eId ) { \n removeListener(gina, $el, eventName);\n }\n }// EO for events\n } //EO for $els\n \n $els = null; $el = null; $elTMP = null; evt = null;\n // reset error display\n //resetErrorsDisplay($form);\n // or\n // $form.target.dataset.ginaFormIsResetting = true;\n // handleErrorsDisplay($form.target, {});\n $form.binded = false;\n \n return $form;\n }\n \n var checkForRuleAlias = function(formRules, $el) {\n var field = $el.name;\n var localRule = formRules[field] || null;\n if ( !localRule ) {\n // looking for regexp aliases from rules\n for (let _r in formRules) {\n if ( /^\\//.test(_r) ) { // RegExp found\n re = _r.match(/\\/(.*)\\//).pop(); \n flags = _r.replace('/'+ re +'/', '');\n // fix escaping \"[\" & \"]\"\n re = re.replace(/\\[/g, '\\\\[').replace(/\\]/g, '\\\\]');\n re = new RegExp(re, flags);\n if ( re.test(field) ) { \n // create new entry \n localRule = formRules[field] = formRules[_r];\n break;\n } \n } \n }\n }\n }\n\n /**\n * bindForm\n *\n * @param {object} $target - DOM element\n * @param {object} [customRule]\n * */\n var bindForm = function($target, customRule) {\n\n var $form = null\n , _id = null\n , rules = ( typeof(local.rules.count() > 0 ) ) ? local.rules : instance.rules\n ;\n\n try {\n if ( $target.getAttribute && $target.getAttribute('id') ) {\n _id = $target.getAttribute('id');\n if ( typeof(instance.$forms[_id]) != 'undefined')\n $form = instance.$forms[_id];\n else\n throw new Error('form instance `'+ _id +'` not found');\n\n } else {\n throw new Error('Validator::bindForm($target, customRule): `$target` must be a DOM element\\n'+err.stack )\n }\n } catch(err) {\n throw new Error('Validator::bindForm($target, customRule) could not bind form `'+ $target +'`\\n'+err.stack )\n }\n\n if ( typeof($form) != 'undefined' && $form.binded) {\n return false\n }\n \n console.debug('binding for: '+ _id);\n \n \n var withRules = false, rule = null, evt = '', proceed = null;\n\n if ( \n typeof(customRule) != 'undefined' \n || \n typeof(_id) == 'string' \n && typeof(rules[_id.replace(/\\-|\\//g, '.')]) != 'undefined' \n ) {\n withRules = true;\n\n if ( customRule && typeof(customRule) == 'object' ) {\n rule = customRule\n } else if ( \n customRule \n && typeof(customRule) == 'string' \n && typeof(rules[customRule.replace(/\\-|\\//g, '.')]) != 'undefined'\n ) { \n rule = getRuleObjByName(customRule.replace(/\\-|\\//g, '.'))\n } else {\n rule = getRuleObjByName(_id.replace(/\\-|\\//g, '.'))\n }\n\n $form.rules = rule;\n if ( envIsDev && isGFFCtx && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar ) {\n // update toolbar\n if (!gina.forms.rules)\n gina.forms.rules = {};\n\n objCallback = {\n id : _id,\n rules : $form.rules\n };\n\n window.ginaToolbar.update('forms', objCallback);\n }\n } else { // form without any rule binded\n $form.rules = {}\n }\n \n // Live check by default - data-gina-form-live-check-enabled\n if ( \n typeof($form.target.dataset.ginaFormLiveCheckEnabled) == 'undefined'\n && $form.rules.count() > 0\n ) {\n $form.target.dataset.ginaFormLiveCheckEnabled = true;\n } else if( typeof($form.target.dataset.ginaFormLiveCheckEnabled) != 'undefined' ) {\n $form.target.dataset.ginaFormLiveCheckEnabled = ( /^true$/i.test($form.target.dataset.ginaFormLiveCheckEnabled) ) ? true : false;\n } else {\n $form.target.dataset.ginaFormLiveCheckEnabled = false;\n }\n\n // form fields collection\n if (!$form.fieldsSet)\n $form.fieldsSet = {};\n\n // binding form elements\n var type = null\n , id = null\n \n // a|links\n , $a = $target.getElementsByTagName('a')\n // input type: checkbox, radio, hidden, text, files, number, date ...\n , $inputs = $target.getElementsByTagName('input')\n // textarea\n , $textareas = $target.getElementsByTagName('textarea')\n // select\n , $select = $target.getElementsByTagName('select')\n , allFormGroupedElements = {}\n , allFormGroupNames = []\n , formElementGroup = {}\n , formElementGroupTmp = null\n , formElementGroupItems = {}\n // file upload\n , $htmlTarget = null \n , $progress = null\n ;\n \n var elId = null;\n \n // BO Binding a - not needed anymore since popin is binding link before binding child forms\n // for (let f = 0, len = $a.length; f < len; ++f) {\n // let isPopinClick = false, hrefAttr = $a[f].getAttribute('href');\n // if ( !hrefAttr || hrefAttr == '' ) {\n // // Preventing popin auto to redirect to current/host page url\n // $a[f].setAttribute('href', '#');\n // isPopinClick = true;\n // }\n // elId = $a[f].getAttribute('id');\n // if (!elId || elId == '') {\n // elId = 'click.'; // by default\n // if ( $target.isPopinContext ) {\n // elId = ( isPopinClick ) ? 'popin.click.' : 'popin.link.';\n // }\n // elId += uuid.v4();\n // $a[f].setAttribute('id', elId)\n // }\n // }\n // EO Binding a\n \n // BO Binding textarea\n for (let f = 0, len = $textareas.length; f < len; ++f) {\n checkForRuleAlias($form.rules, $textareas[f]);\n elId = $textareas[f].getAttribute('id');\n if (!elId || elId == '') {\n elId = 'textareas.' + uuid.v4();\n $textareas[f].setAttribute('id', elId)\n }\n if (!$form.fieldsSet[ elId ]) {\n let defaultValue = $textareas[f].value || '';\n // // just in case\n // if ( \n // typeof($form.fieldsSet[elId]) != 'undefined'\n // && typeof($form.fieldsSet[elId].defaultValue) != 'undefined'\n // ) {\n // defaultValue = $form.fieldsSet[elId].defaultValue;\n // }\n $form.fieldsSet[elId] = {\n id: elId,\n name: $textareas[f].name || null,\n value: $textareas[f].value || '',\n defaultValue: defaultValue\n }\n }\n // Adding live check\n if (/^true$/i.test($form.target.dataset.ginaFormLiveCheckEnabled) ) {\n registerForLiveChecking($form, $textareas[f]);\n }\n \n }\n // EO Binding textarea\n \n // BO Binding input \n for (let f = 0, len = $inputs.length; f < len; ++f) {\n checkForRuleAlias($form.rules, $inputs[f]);\n elId = $inputs[f].getAttribute('id');\n if (!elId || elId == '') {\n elId = 'input.' + uuid.v4();\n $inputs[f].setAttribute('id', elId)\n }\n\n if (!$form.fieldsSet[ elId ]) {\n let defaultValue = $inputs[f].value;\n if (/$(on|true|false)$/i.test(defaultValue)) {\n defaultValue = (/$(on|true)$/i.test(defaultValue)) ? true : false;\n }\n // just in case\n // if ( \n // typeof($form.fieldsSet[elId]) != 'undefined'\n // && typeof($form.fieldsSet[elId].defaultValue) != 'undefined'\n // ) {\n // defaultValue = $form.fieldsSet[elId].defaultValue;\n // }\n \n $form.fieldsSet[elId] = {\n id: elId,\n name: $inputs[f].name || null,\n value: defaultValue || ( !/^(checkbox|radio)$/i.test($inputs[f].type) ) ? \"\" : $inputs[f].checked,\n defaultValue: ( !/^(checkbox|radio)$/i.test($inputs[f].type) ) ? defaultValue : $inputs[f].checked\n }\n \n if ( /^(checkbox|radio)$/i.test($inputs[f].type) && typeof($form.fieldsSet[elId].defaultChecked) == 'undefined' ) {\n \n \n $form.fieldsSet[elId].defaultChecked = ( \n /^(true|on)$/i.test($inputs[f].checked)\n ||\n /^(true|on)$/.test(defaultValue)\n && /^(checkbox)$/i.test($inputs[f].type) \n ) ? true : false;\n \n if (/^radio$/i.test($inputs[f].type) ) {\n $form.fieldsSet[elId].value = $inputs[f].value;\n $form.fieldsSet[elId].defaultValue = $inputs[f].value;\n }\n }\n }\n \n // Adding live check\n if (/^true$/i.test($form.target.dataset.ginaFormLiveCheckEnabled) ) {\n registerForLiveChecking($form, $inputs[f]);\n }\n \n formElementGroupTmp = $inputs[f].getAttribute('data-gina-form-element-group');\n if (formElementGroupTmp) {\n // recording group names\n if ( allFormGroupNames.indexOf(formElementGroupTmp) < 0 ) {\n allFormGroupNames.push(formElementGroupTmp);\n } \n \n let _name = $inputs[f].getAttribute('name') || elId;\n if (_name === elId) {\n $inputs[f].setAttribute('name', elId)\n }\n allFormGroupedElements[elId] = {\n id : elId,\n name : _name,\n group : formElementGroupTmp,\n target : $inputs[f]\n };\n formElementGroup[ $inputs[f].name ] = new RegExp('^'+formElementGroupTmp.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'));\n // Attention, this means that all dependening field will be\n // ignored on validation, unless you write a rule that\n // will override this behavior or else your fields won't be submited\n // this behaviour only applies to Form Grouped Elements\n if (withRules) {\n if ( typeof($form.rules[ $inputs[f].name ]) == 'undefined') {\n $form.rules[ $inputs[f].name ] = {}\n }\n // By default exclude groups only if not required\n // Those will be included if member of selected group\n // See : handleGroupDependencies() \n if ( \n typeof($form.rules[ $inputs[f].name ].isRequired) == 'undefined'\n || !$form.rules[ $inputs[f].name ].isRequired\n ) {\n $form.rules[ $inputs[f].name ].exclude = true;\n } \n }\n }\n // handling groups dependencies\n if ( formElementGroup.count() > 0 ) {\n var formElementGroupName = null, formElementGroupType = null, formElementIsIgnored = null;\n for ( var g in formElementGroup ) {\n if ($inputs[f].name == g) continue;\n // checkbox group init \n formElementGroupName = $inputs[f].getAttribute('data-gina-form-element-group') || null;\n if ( formElementGroup[g].test($inputs[f].name) ) {\n $inputs[f].disabled = true; // by default \n if ( typeof(formElementGroupItems[ g ]) == 'undefined' ) {\n formElementGroupItems[ g ] = {}\n }\n formElementGroupItems[ g ][ $inputs[f].name ] = $inputs[f];\n }\n \n }\n }\n // Binding upload file\n // todo : data-gina-file-autosend=\"false\" when false, don't trigger the sending to the backend\n // todo : progress bar\n // todo : on('success') -> preview\n if ( /^file$/i.test($inputs[f].type) ) { \n // Binding upload trigger\n // trigger is by default you {input.id} + '-trigger' \n // e.g.: <input type=\"file\" id=\"my-upload\" name=\"my-upload\">\n // => <button type=\"button\" id=\"my-upload-trigger\">Choose a file</button>\n // But you can use atrtibute `data-gina-form-upload-trigger` to override it \n var uploadTriggerId = $inputs[f].getAttribute('data-gina-form-upload-trigger');\n if (!uploadTriggerId)\n uploadTriggerId = $inputs[f].id;\n \n var $upload = null\n , $uploadTrigger = null\n ;\n // `$htmlTarget` cannot be used if you need to add a listner on the searched element\n $htmlTarget = new DOMParser().parseFromString($target.innerHTML, 'text/html');\n if (uploadTriggerId) { \n $uploadTrigger = document.getElementById(uploadTriggerId);\n //$uploadTrigger = $htmlTarget.getElementById(uploadTriggerId);\n }\n var $errorContainer = document.getElementById($inputs[f].id + '-error');\n checkUploadUrlActions($inputs[f], $errorContainer ); \n \n // check default UploadResetOrDeleteTrigger state\n // required to bind delete - look for all delete triggers\n // $deleteTriggers = []; \n // bindUploadResetOrDeleteTrigger(bindingType, $uploadTrigger, index);\n // eg.: document-files-0-preview; if $inputs[f].id === `document-files-0`\n var $previewContainer = $htmlTarget.getElementById(uploadTriggerId + '-preview');\n if ( \n $previewContainer \n && $uploadTrigger\n && !/none/i.test(window.getComputedStyle($previewContainer).display)\n // for safety\n && !/none/i.test($previewContainer.parentElement.style.display)\n ) {\n \n var $deleteLink = null, index = 0, bindingType = 'delete'; \n console.debug('preview is visible ...');\n $uploadTrigger.customFiles = [];\n $uploadTrigger.form = $target;\n var $els = $previewContainer.childNodes;\n for (let i = 0, len = $els.length; i < len; i++) {\n let $img = null;\n if ( /ul/i.test($els[i].tagName) ) {\n for (let e = 0, eLen = $els[i].length; e < eLen; e++) {\n //let $li = new DOMParser().parseFromString($els[i].innerHTML, 'text/html');\n let $li = $$els[i];\n for (let l = 0, lLen = $li.length; l < lLen; l++) {\n if ( /img/i.test($li[l]) ) {\n $img = $li[l];\n $img.setAttribute('');\n \n index++;\n }\n }\n \n } \n } else if ( /img/i.test($els[i].tagName) ) {\n $img = $els[i];\n deleteLinkId = uploadTriggerId + '-'+index+'-delete-trigger';\n let file = $img.src.substr($img.src.lastIndexOf('/')+1);\n $uploadTrigger.customFiles.push({\n name: file,\n deleteLinkId: deleteLinkId\n });\n // bind reset trigger\n bindUploadResetOrDeleteTrigger(bindingType, $uploadTrigger, index);\n \n index++;\n }\n }\n }\n \n // binding upload trigger\n // if ( $uploadTrigger ) {\n // $uploadTrigger.setAttribute('data-gina-form-upload-target', $inputs[f].id);\n // addListener(gina, $uploadTrigger, 'click', function(event) {\n // event.preventDefault();\n // var $el = event.target;\n \n // var fileElemId = $el.getAttribute('data-gina-form-upload-target') || null; \n // if (fileElemId)\n // $upload = document.getElementById(fileElemId);\n \n // if ($upload) {\n // removeListener(gina, $upload, 'click');\n // $upload.value = '';// force reset : != multiple\n // triggerEvent(gina, $upload, 'click', event.detail);\n // } \n // });\n // }\n \n // binding file element == $upload\n // setTimeout(() => {\n // removeListner(gina, $inputs[f], 'change');\n // }, 0); \n addListener(gina, $inputs[f], 'change', function(event) {\n event.preventDefault();\n var $el = event.currentTarget;\n // [0] is for a single file, when multiple == false\n //var files = Array.from($el.files);\n var files = $el.files;\n // used for validation & onUploadResetOrDelete\n $el.customFiles = Array.from(files);\n if (!files.length ) return false;\n \n \n \n \n // $progress = $($(this).parent().find('.progress'));\n var url = $el.getAttribute('data-gina-form-upload-action'); \n var name = $el.getAttribute('name');\n var fileId = name; \n var uploadFormId = 'gina-upload-' + name.replace(/\\[/g, '-').replace(/\\]/g, '-' + $form.id);\n $el.setAttribute('data-gina-form-virtual', uploadFormId);\n var eventOnSuccess = $el.getAttribute('data-gina-form-upload-on-success');\n var eventOnError = $el.getAttribute('data-gina-form-upload-on-error');\n var errorField = null;\n \n if (files.length > 0) {\n \n // create form if not exists \n var $uploadForm = null, $activePopin = null; \n if ( isPopinContext() ) {\n // getting active popin\n $activePopin = gina.popin.getActivePopin();\n $activePopin.$target = new DOMParser().parseFromString($activePopin.target.outerHTML, 'text/html');\n // binding to DOM\n $activePopin.$target.getElementById($activePopin.id).innerHTML = document.getElementById($activePopin.id).innerHTML;\n \n $uploadForm = $activePopin.$target.getElementById(uploadFormId); \n } else {\n $uploadForm = document.getElementById(uploadFormId);\n }\n \n if ( !$uploadForm ) {\n try {\n $uploadForm = getFormById(uploadFormId) || null;\n } catch (noExistingFormErr) {\n // do nothing\n }\n \n if (!$uploadForm) {\n $uploadForm = (isPopinContext()) \n ? $activePopin.$target.createElement('form') \n : document.createElement('form');\n }\n \n\n // adding form attributes\n $uploadForm.id = uploadFormId;\n // setAttribute() not needed ?\n //$uploadForm.setAttribute('id', uploadFormId);\n $uploadForm.action = url;\n $uploadForm.enctype = 'multipart/form-data';\n $uploadForm.method = 'POST';\n \n \n \n if ( typeof($el.form) != 'undefined' ) {\n \n // adding virtual fields\n var fieldPrefix = 'files'; // by default\n var fieldName = $el.getAttribute('data-gina-form-upload-prefix') || $el.name || $el.getAttribute('name');\n var fieldId = $el.id || $el.getAttribute('id');\n \n var hasPreviewContainer = false;\n var previewContainer = $el.getAttribute('data-gina-form-upload-preview') || fieldId + '-preview';\n previewContainer = (isPopinContext())\n ? $activePopin.$target.getElementById(previewContainer)\n : document.getElementById(previewContainer); \n \n if ( typeof(previewContainer) != 'undefined' ) {\n hasPreviewContainer = true; \n }\n \n if (fieldName) {\n fieldPrefix = fieldName\n }\n \n var hiddenFields = []\n , hiddenFieldObject = null \n , mandatoryFields = [\n 'name'\n , 'group'\n , 'originalFilename'\n , 'ext'\n , 'encoding'\n , 'size'\n , 'height' // will be removed depending on the mime type\n , 'width' // will be removed depending on the mime type\n , 'location'\n , 'mime'\n , 'preview'\n ]\n , formInputsFields = $el.form.getElementsByTagName('INPUT')\n , fieldType = null\n , hiddenField = null\n , _userName = null\n , _altId = null\n , _name = null\n , _nameRe = null\n , subPrefix = null\n , uploadFields = {}\n ;\n \n for (var _f = 0, _fLen = files.length; _f < _fLen; ++_f) { // for each file \n // binding upload reset trigger\n bindUploadResetOrDeleteTrigger('reset', $el, _f); \n hiddenFields[_f] = null;\n subPrefix = fieldPrefix + '['+ _f +']';\n _nameRe = new RegExp('^'+subPrefix.replace(/\\[/g, '\\\\[').replace(/\\]/g, '\\\\]'));\n // collecting existing DOM fields\n for (var h = 0, hLen = formInputsFields.length; h < hLen; ++h) {\n fieldType = formInputsFields[h].getAttribute('type');\n hiddenField = null;\n _name = null, _userName = null;\n errorField= formInputsFields[h].getAttribute('data-gina-form-upload-error') || fieldId + '-error' || null;\n \n if (fieldType && /hidden/i.test(fieldType) ) {\n hiddenField = formInputsFields[h];\n \n _name = ( /\\[\\w+\\]$/i.test(hiddenField.name) ) \n ? hiddenField.name.match(/\\[\\w+\\]$/)[0].replace(/\\[|\\]/g, '') \n : hiddenField.name; \n _userName = ( /\\[\\w+\\]$/i.test(hiddenField.name) ) \n ? hiddenField.name.match(/\\[\\w+\\]$/)[0].replace(/\\[|\\]/g, '') \n : hiddenField.name;\n \n // mandatory informations\n if (\n hiddenField \n && typeof(_name) != 'undefiend' \n && mandatoryFields.indexOf( _name ) > -1\n && _nameRe.test( hiddenField.name )\n ) {\n \n if (!hiddenFields[_f] )\n hiddenFields[_f] = {};\n \n if ( /\\[preview\\]/i.test(hiddenField.name) ) {\n if ( typeof(hiddenFields[_f].preview) == 'undefined' )\n hiddenFields[_f].preview = {};\n \n hiddenFields[_f].preview[_name] = hiddenField;\n } else {\n hiddenFields[_f][_name] = hiddenField;\n } \n } else if (\n hiddenField \n && typeof(_name) != 'undefiend' \n && mandatoryFields.indexOf( _name ) < 0\n && _nameRe.test( hiddenField.name )\n ) { // defined by user\n if (!hiddenFields[_f] )\n hiddenFields[_f] = {};\n \n if ( /\\[preview\\]/i.test(hiddenField.name) ) {\n if ( typeof(hiddenFields[_f].preview) == 'undefined' )\n hiddenFields[_f].preview = {};\n \n hiddenFields[_f].preview[_userName] = hiddenField;\n } else {\n hiddenFields[_f][_userName] = hiddenField;\n } \n }\n } \n }\n \n // completing by adding non-declared mandatoring fields in the DOM: all but preview\n for (var m = 0, mLen = mandatoryFields.length; m < mLen; ++m) {\n // optional, must be set by user\n // needs recheck \n if (!hiddenFields[_f] )\n hiddenFields[_f] = {};\n \n if ( typeof(hiddenFields[_f][ mandatoryFields[m] ]) == 'undefined' ) {\n \n _name = fieldPrefix +'['+ _f +']['+ mandatoryFields[m] +']'; \n // create input & add it to the form\n $newVirtualField = document.createElement('input');\n $newVirtualField.type = 'hidden';\n $newVirtualField.id = 'input.' + uuid.v4();\n $newVirtualField.name = _name;\n $newVirtualField.value = '';\n \n $el.form.appendChild($newVirtualField);\n hiddenFields[_f][ mandatoryFields[m] ] = $el.form[$el.form.length-1];// last added\n }\n \n }\n \n } // EO for files\n \n $uploadForm.uploadProperties = { \n id : $el.form.id || $el.getAttribute('id'),\n uploadTriggerId : $el.id,\n $form : $el.form,\n errorField : errorField,\n mandatoryFields : mandatoryFields,\n uploadFields : hiddenFields,\n hasPreviewContainer : hasPreviewContainer,\n isPopinContext : isPopinContext()\n };\n if (hasPreviewContainer) {\n $uploadForm.uploadProperties.previewContainer = previewContainer;\n }\n }\n \n if (eventOnSuccess)\n $uploadForm.setAttribute('data-gina-form-event-on-submit-success', eventOnSuccess);\n else\n $uploadForm.setAttribute('data-gina-form-event-on-submit-success', 'onGenericXhrResponse');\n \n if (eventOnError)\n $uploadForm.setAttribute('data-gina-form-event-on-submit-error', eventOnError);\n else\n $uploadForm.setAttribute('data-gina-form-event-on-submit-error', 'onGenericXhrResponse');\n \n \n // adding for to current document\n if (isPopinContext()) {\n //$activePopin.$target.appendChild($uploadForm)\n document.getElementById($activePopin.id).appendChild($uploadForm)\n } else {\n document.body.appendChild($uploadForm)\n } \n }\n \n // binding form\n try {\n var $uploadFormValidator = getFormById(uploadFormId);\n // create a FormData object which will be sent as the data payload \n var formData = new FormData();\n // add the files to formData object for the data payload\n var file = null; \n for (var l = 0, lLen = files.length; l < lLen; ++l) {\n file = files[l];\n formData.append(fileId, file, file.name);\n }\n \n \n $uploadFormValidator\n // .on('error', function(e, result) {\n // console.error('[error] ', '\\n(e)' + e, '\\n(result)' + result)\n // })\n // .on('success', function(e, result){\n \n // var $el = e.target;\n // var $preview = null, $ul = null, $li = null, $img = null;\n // var previewId = $el.getAttribute('data-gina-form-upload-preview') || null;\n // if (previewId)\n // $preview = document.getElementById(previewId);\n \n \n // var files = result.files;\n // if ($preview) {\n // $preview.innerHTML = '';\n // $ul = document.createElement(\"ul\");\n // for (var f = 0, fLen = files.length; f<fLen; ++f) {\n // $li = document.createElement(\"li\");\n // $img = document.createElement(\"img\");\n \n // $img.src = files[f].tmpSrc;\n // $img.width = files[f].width;\n // $img.height = files[f].height;\n \n // $li.appendChild($img);\n // $ul.appendChild($li);\n // }\n // $preview.appendChild($ul);\n // }\n \n // })\n /**.on('progress', function(evt, result) {\n \n percentComplete = result.progress;\n \n $progress.text(percentComplete + '%');\n $progress.width(percentComplete + '%');\n \n if (percentComplete === 100) {\n $progress.html('Done');\n }\n \n // if (evt.lengthComputable) {\n // // calculate the percentage of upload completed\n // var percentComplete = evt.loaded / evt.total;\n // percentComplete = parseInt(percentComplete * 100);\n \n // // update the Bootstrap progress bar with the new percentage\n // $progress.text(percentComplete + '%');\n // $progress.width(percentComplete + '%');\n \n // // once the upload reaches 100%, set the progress bar text to done\n // if (percentComplete === 100) {\n // $progress.html('Done');\n // }\n \n // }\n }) */ \n .send(formData, { withCredentials: true/** , isSynchrone: true*/ });\n \n } catch (formErr) {\n throw formErr;\n } \n }\n });\n \n \n }\n }// EO Binding input\n\n var updateSelect = function($el, $form) {\n $el.setAttribute('data-value', $el.value);\n // If Live check enabled, proceed to silent validation\n if ( /^(true)$/i.test($form.target.dataset.ginaFormLiveCheckEnabled && $form.rules.count() > 0) ) {\n var localField = {}, $localField = {}, $localForm = null;\n $localForm = $el.form;//event.target.form\n localField[event.target.name] = event.target.value;\n $localField[event.target.name] = event.target;\n \n instance.$forms[$localForm.getAttribute('id')].isValidating = true;\n validate(event.target, localField, $localField, $form.rules, function onLiveValidation(result){\n instance.$forms[$localForm.getAttribute('id')].isValidating = false;\n var isFormValid = result.isValid();\n //console.debug('onSilentPreGlobalLiveValidation: '+ isFormValid, result);\n if (isFormValid) {\n //resetting error display\n handleErrorsDisplay($localForm, {}, result.data, event.target.name);\n } else { \n handleErrorsDisplay($localForm, result.error, result.data, event.target.name);\n }\n //updateSubmitTriggerState( $localForm, isFormValid );\n // data-gina-form-required-before-submit\n //console.debug('====>', result.isValid(), result);\n \n // Global check required: on all fields\n var $gForm = $localForm, gFields = null, $gFields = null, gRules = null;\n var gValidatorInfos = getFormValidationInfos($gForm, rules);\n gFields = gValidatorInfos.fields;\n $gFields = gValidatorInfos.$fields;\n var formId = $gForm.getAttribute('id');\n gRules = instance.$forms[formId].rules;\n // Don't be tempted to revome fields that has already been validated\n instance.$forms[formId].isValidating = true;\n validate($gForm, gFields, $gFields, gRules, function onSilentGlobalLiveValidation(gResult){\n instance.$forms[formId].isValidating = false;\n console.debug('[updateSelect]: onSilentGlobalLiveValidation: '+ gResult.isValid(), gResult);\n var isFormValid = gResult.isValid();\n updateSubmitTriggerState( $gForm, isFormValid);\n once = false;\n })\n \n });\n }\n };\n // BO binding select\n var selectedIndex = null, selectedValue = null; \n for (var s = 0, sLen = $select.length; s < sLen; ++s) {\n checkForRuleAlias($form.rules, $select[s]);\n \n elId = $select[s].getAttribute('id');\n \n if (elId && /^gina\\-toolbar/.test(elId)) continue;\n\n if (!elId || elId == '') {\n elId = 'select.' + uuid.v4();\n $select[s].setAttribute('id', elId)\n }\n \n formElementGroupTmp = $select[s].getAttribute('data-gina-form-element-group');\n if (formElementGroupTmp) {\n let _name = $select[s].getAttribute('name') || elId;\n if (_name === elId) {\n $select[s].setAttribute('name', elId)\n }\n allFormGroupedElements[elId] = {\n id : elId,\n name : _name,\n group : formElementGroupTmp,\n target : $select[s]\n };\n }\n \n addListener(gina, $select[s], 'change', function(event) {\n var $el = event.target;\n \n if (/select/i.test($el.type) ) { \n updateSelect($el, $form);\n } \n });\n \n\n if ($select[s].options && !$form.fieldsSet[ elId ]) {\n selectedIndex = 0;\n selectedValue = $select[s].getAttribute('data-value') || null;\n if ( selectedValue ) {\n for (var o = 0, oLen = $select[s].options.length; o < oLen; ++o ) {\n if ( $select[s].options[o].value == selectedValue) {\n selectedIndex = o;\n $select[s].selectedIndex = selectedIndex;\n break\n }\n }\n }\n \n if ( typeof($select[s].options[$select[s].selectedIndex]) != 'undefined' && $select[s].options[ $select[s].selectedIndex ].index ) {\n selectedIndex = $select[s].options[ $select[s].selectedIndex ].index\n }\n\n $form.fieldsSet[ elId ] = {\n id : elId,\n name : $select[s].name || null,\n value : $select[s].options[ selectedIndex ].value || selectedValue || null,\n selectedIndex : selectedIndex || 0\n };\n\n // update select\n if ( typeof($select[s].selectedIndex) != 'undefined' ) {\n $select[s].options[ selectedIndex ].selected = true;\n $select[s].setAttribute('data-value', $select[s].options[ selectedIndex ].value);\n }\n\n }\n }// EO binding select\n \n // group dependencies handling\n var updateReletadItems = function(elId, group, excluded, isCalledHasDependency) {\n \n if ( typeof(isCalledHasDependency) == 'undefined' ) {\n isCalledHasDependency = false;\n }\n \n if ( typeof(allFormGroupedElements[elId]) == 'undefined' ) {\n throw new Error('Radio & Checkbox dependencies not met: you must use the ID attribue of the `master element` as the `data-gina-form-element-group`')\n }\n \n var elIdIsChecked = null\n , re = null\n , re2 = null\n , namedId = elId.replace(/\\-|\\_|\\@|\\#|\\.|\\[|\\]/g, '\\\\$&') \n //, name = $el.getAttribute('name').replace(/\\-|\\_|\\@|\\#|\\.|\\[|\\]/g, '\\\\$&')\n ;\n elIdIsChecked = allFormGroupedElements[elId].target.checked;\n //console.debug('current id ', elId, excluded);\n for (let id in allFormGroupedElements) {\n // ignore triggers\n if ( /radio|checkbox/i.test(allFormGroupedElements[id].target.type) )\n continue;\n \n let hasBeenUpdated = false; \n re = new RegExp(namedId);\n re2 = new RegExp(group); \n \n if ( \n re.test(allFormGroupedElements[id].group) && re2.test(allFormGroupedElements[id].group) \n ||\n re.test(allFormGroupedElements[id].group)\n ) {\n // init default state: disable all;\n allFormGroupedElements[id].target.disabled = true;\n // adding custom rule for this case\n if ( typeof($form.rules[ allFormGroupedElements[id].name ]) == 'undefined' ) {\n $form.rules[ allFormGroupedElements[id].name ] = {}\n }\n $form.rules[ allFormGroupedElements[id].name ].exclude = true;\n \n // triggered by click on the radio group \n if (isCalledHasDependency) {\n //console.debug('In Group #1 ', 'excluded:'+excluded, 'disabled:'+allFormGroupedElements[id].target.disabled, allFormGroupedElements[id].name, checkBoxGroup, ' VS ', allFormGroupedElements[id].group); \n allFormGroupedElements[id].target.disabled = (elIdIsChecked) ? false : true;\n $form.rules[ allFormGroupedElements[id].name ].exclude = (elIdIsChecked) ? false : true;\n //console.debug('In Group #1 fixed to -> ', 'excluded:'+excluded, 'disabled:'+allFormGroupedElements[id].target.disabled);\n continue;\n }\n // triggered by click on the checkbox\n //console.debug('In Group #2 ', 'excluded:'+excluded, 'disabled:'+allFormGroupedElements[id].target.disabled, allFormGroupedElements[id].name, checkBoxGroup, ' VS ', allFormGroupedElements[id].group);\n allFormGroupedElements[id].target.disabled = excluded;\n $form.rules[ allFormGroupedElements[id].name ].exclude = excluded;\n //console.debug('In Group #2 fixed to -> ', 'excluded:'+excluded, 'disabled:'+allFormGroupedElements[id].target.disabled);\n continue;\n }\n //console.debug('elId: '+elId, 'isCalledHasDependency:'+isCalledHasDependency, 'hasBeenUpdated:'+ hasBeenUpdated, 'excluded:'+excluded, 'disabled:'+allFormGroupedElements[id].target.disabled, allFormGroupedElements[id].name, 'elIdIsChecked:'+elIdIsChecked, 'inGroup:'+re.test(allFormGroupedElements[id].group) );\n \n }\n \n return\n };\n var handleCheckBoxGroupDependencies = function($form, $el, checkBoxGroup, isCalledHasDependency) {\n \n \n if ( typeof(isCalledHasDependency) == 'undefined' ) {\n isCalledHasDependency = false;\n }\n if (isCalledHasDependency && typeof(allFormGroupedElements[$el.id]) != 'undefined' ) {\n var excluded = /true/i.test($el.checked) ? false : true;\n return updateReletadItems($el.id, allFormGroupedElements[$el.id].group, excluded, isCalledHasDependency)\n }\n \n \n var item = $el.name;\n if (withRules && typeof($form.rules[item]) == 'undefined' ) { \n $form.rules[item] = {}\n } \n if ( /^true$/i.test($el.checked) ) { \n if (withRules) {\n $form.rules[item].exclude = false;\n if ( typeof(allFormGroupedElements[$el.id]) != 'undefined' ) {\n updateReletadItems($el.id, allFormGroupedElements[$el.id].group, false, isCalledHasDependency)\n }\n }\n } else {\n //elGroup[item].disabled = true;\n if (withRules) {\n $form.rules[item].exclude = true;\n if ( typeof(allFormGroupedElements[$el.id]) != 'undefined' ) {\n updateReletadItems($el.id, allFormGroupedElements[$el.id].group, true, isCalledHasDependency)\n }\n }\n }\n };\n var updateCheckBox = function($el, isInit) {\n if ( typeof(isInit) == 'undefined' ) {\n isInit = false;\n }\n \n var triggerHandleCheckBoxGroupDependencies = function($el, checkBoxGroup, isExcluded) {\n if (checkBoxGroup) {\n handleCheckBoxGroupDependencies($form, $el, checkBoxGroup);\n } else { \n for (let id in allFormGroupedElements) {\n if ( \n re.test(allFormGroupedElements[id].group)\n ||\n re.test(allFormGroupedElements[id].target.getAttribute('data-gina-form-element-group'))\n ) {\n allFormGroupedElements[id].target.disabled = isExcluded; \n }\n }\n } \n }\n \n // Preventing jQuery setting `on` value when input is not checked\n if (isInit && /^(on)$/i.test($el.value) && !$el.checked) {\n $el.value = false\n }\n var localValue = $el.getAttribute('data-value') || $el.getAttribute('value') || $el.value;\n localValue = (/^(true|on)$/.test(localValue)) ? true : localValue;\n \n if (localValue === '') {\n localValue = false\n }\n var isLocalBoleanValue = ( /^(true|on|false)$/i.test(localValue) ) ? true : false;\n if (isInit && isLocalBoleanValue) { // on checkbox init\n // update checkbox initial state\n // Value defines checked state by default\n if ( /^true$/i.test(localValue) && !$el.checked) {\n $el.checked = true;\n } else if ( /^false$/i.test(localValue) && $el.checked) {\n $el.checked = false;\n }\n }\n var checked = $el.checked;\n \n var checkBoxGroup = $el.getAttribute('data-gina-form-element-group') || null;\n var re = new RegExp($el.id.replace(/\\-|\\_|\\@|\\#|\\.|\\[|\\]/g, '\\\\$&'));\n // set to checked if not checked: false -> true\n if ( !checked || checked == 'null' || checked == 'false' || checked == '' ) {\n\n // prevents ticking behavior\n if (!isInit) {\n setTimeout(function () {\n $el.checked = false;\n // means that the checkbox is member of another group\n triggerHandleCheckBoxGroupDependencies($el, checkBoxGroup, true);\n updateGroupChildrenState($el);\n }, 0);\n } else {\n updateGroupChildrenState($el);\n }\n \n \n $el.removeAttribute('checked');\n if (isLocalBoleanValue) {\n $el.value = false;\n $el.setAttribute('value', 'false');\n if ( typeof($el.getAttribute('data-value') != 'undefined' ) )\n $el.setAttribute('data-value', 'false');\n }\n \n \n } else { \n \n // prevents ticking behavior\n if (!isInit) {\n setTimeout(function () {\n $el.checked = true;\n // means that the checkbox is member of another group\n triggerHandleCheckBoxGroupDependencies($el, checkBoxGroup, false); \n updateGroupChildrenState($el);\n }, 0);\n $el.setAttribute('checked', 'checked');\n } else {\n updateGroupChildrenState($el);\n }\n \n if (isLocalBoleanValue) {\n $el.value = true;\n $el.setAttribute('value', true);\n if ( typeof($el.getAttribute('data-value') != 'undefined' ) )\n $el.setAttribute('data-value', true);\n }\n \n }\n };\n \n var updateGroupChildrenState = function($groupMaster) {\n var re = new RegExp($groupMaster.id.replace(/\\-|\\_|\\@|\\#|\\.|\\[|\\]/g, '\\\\$&'));\n // Handle extended groups\n for (let id in allFormGroupedElements) {\n if ( \n /checkbox/i.test(allFormGroupedElements[id].target.type) && re.test(allFormGroupedElements[id].group)\n ||\n /checkbox/i.test(allFormGroupedElements[id].target.type) && re.test(allFormGroupedElements[id].target.getAttribute('data-gina-form-element-group'))\n ) {\n handleCheckBoxGroupDependencies($form, allFormGroupedElements[id].target, allFormGroupedElements[id].group, true); \n }\n }\n }\n \n // When binding children element to the radio, you must used the radio.id as the element group\n // Because the name attribute of the radio can also be used to group multiple radio field\n // On master: <input type=\"radio\" id=\"invoice-type-balance\" name=\"action[addFromExisting]\" value=\"balanceFlow\">\n // On children: <input type=\"checkbox\" data-gina-form-element-group=\"invoice-type-balance\" value=\"someValue\">\n var handleGroupDependencies = function($el, isOnResetMode) {\n isOnResetMode = ( typeof(isOnResetMode) != 'undefined' && isOnResetMode) ? true: false;\n \n //console.debug('reset: '+isOnResetMode, $el.id, $el.checked);\n var extendedGroupName = $el.id.replace(/\\-|\\_|\\@|\\#|\\.|\\[|\\]/g, '\\\\$&')\n , re = null\n ;\n // parse grouped elements: allFormGroupedElements\n // init\n re = new RegExp(extendedGroupName);\n for (let id in allFormGroupedElements) { \n if (!/checkbox|radio/i.test(allFormGroupedElements[id].target.type)) {\n allFormGroupedElements[id].target.disabled = true;\n // adding custom rule for this case\n if ( typeof($form.rules[ allFormGroupedElements[id].name ]) == 'undefined' ) {\n $form.rules[ allFormGroupedElements[id].name ] = {}\n }\n $form.rules[ allFormGroupedElements[id].name ].exclude = true;\n }\n \n if ( \n re.test(allFormGroupedElements[id].group) \n ||\n re.test(allFormGroupedElements[id].target.getAttribute('data-gina-form-element-group').replace(/\\-|\\_|\\@|\\#|\\.|\\[|\\]/g, '\\\\$&')) \n ) { \n // init default\n allFormGroupedElements[id].target.disabled = true;\n // adding custom rule for this case\n if ( typeof($form.rules[ allFormGroupedElements[id].name ]) == 'undefined' ) {\n $form.rules[ allFormGroupedElements[id].name ] = {}\n }\n \n if (/^(true|on)$/i.test($el.checked)) {\n allFormGroupedElements[id].target.disabled = false;\n $form.rules[ allFormGroupedElements[id].name ].exclude = false;\n } else {\n allFormGroupedElements[id].target.disabled = true; \n $form.rules[ allFormGroupedElements[id].name ].exclude = true;\n }\n }\n }\n // Handle extended groups\n updateGroupChildrenState($el);\n }\n \n // BO Binding radio\n var radioGroup = null;\n var updateRadio = function($el, isInit, isTriggedByUser) {\n isInit = ( typeof(isInit) == 'undefined' || !isInit ) ? false : true;\n isTriggedByUser = ( typeof(isTriggedByUser) == 'undefined' || !isTriggedByUser ) ? false : true;\n \n var checked = $el.checked, evt = null;\n var isBoolean = /^(true|false)$/i.test($el.value);\n radioGroup = document.getElementsByName($el.name);\n\n // loop if radio group\n for (let r = 0, rLen = radioGroup.length; r < rLen; ++r) {\n if (radioGroup[r].id !== $el.id && checked) {\n radioGroup[r].checked = false;\n radioGroup[r].removeAttribute('checked');\n handleGroupDependencies(radioGroup[r], true)\n }\n }\n \n \n if (isInit) {\n handleGroupDependencies($el);\n return;\n }\n\n if ( !checked || checked == 'null' || checked == 'false' || checked == '' ) {\n\n // prevents ticking behavior\n setTimeout(function () {\n if (isTriggedByUser) {\n handleGroupDependencies($el);\n return;\n } \n $el.checked = true;\n $el.setAttribute('checked', 'checked');\n }, 0)\n \n } else {\n\n // prevents ticking behavior\n setTimeout(function () {\n if (isTriggedByUser) {\n handleGroupDependencies($el);\n return;\n }\n $el.checked = false;\n $el.removeAttribute('checked');\n }, 0)\n }\n\n if (isBoolean) { // force boolean value\n $el.value = (/^true$/.test($el.value)) ? true : false\n }\n // fix added on 2020/09/25 : \n return;\n }// EO Binding radio\n \n for (var i = 0, iLen = $inputs.length; i < iLen; ++i) {\n type = $inputs[i].getAttribute('type');\n\n if ( typeof($inputs[i].id) == 'undefined' || $inputs[i].id == '' ) {\n $inputs[i].id = type +'-'+ uuid.v4();\n $inputs[i].setAttribute('id', $inputs[i].id)\n }\n\n\n // recover default state only on value === true || false || on\n if ( \n typeof(type) != 'undefined' \n && /^checkbox$/i.test(type) \n ) {\n \n // if is master of a group, init children default state \n if ( \n $inputs[i].disabled \n && allFormGroupNames.indexOf($inputs[i].id) > -1 \n ||\n !$inputs[i].checked \n && allFormGroupNames.indexOf($inputs[i].id) > -1\n ) {\n // updateGroupChildrenState($inputs[i]);\n let re = new RegExp( $inputs[i].id.replace(/\\-|\\_|\\@|\\#|\\.|\\[|\\]/g, '\\\\$&') ); \n for (let childElement in allFormGroupedElements ) {\n if ( re.test(allFormGroupedElements[childElement].group) ) {\n allFormGroupedElements[childElement].target.disabled = true;\n }\n } \n } \n\n evt = 'change.'+ $inputs[i].id;\n proceed = function ($el, evt) {\n\n // recover default state only on value === true || false \n addListener(gina, $el, evt, function(event) { \n updateCheckBox(event.target);\n \n triggerEvent(gina, event.target, 'changed.'+ event.target.id); \n });\n\n // default state recovery\n updateCheckBox($el, true); \n }\n\n if ( typeof(gina.events[evt]) != 'undefined' && gina.events[evt] == $inputs[i].id ) {\n removeListener(gina, $inputs[i], evt);\n proceed($inputs[i], evt)\n\n } else {\n proceed($inputs[i], evt)\n }\n\n } else if (\n typeof(type) != 'undefined' \n && /^radio$/i.test(type) \n ) {\n\n evt = $inputs[i].id;\n //evt = 'change.'+ $inputs[i].id;\n\n proceed = function ($el, evt) {\n // recover default state\n addListener(gina, $el, evt, function(event) {\n //cancelEvent(event);\n updateRadio(event.target);\n \n triggerEvent(gina, event.target, 'changed.'+ event.target.id); \n });\n \n // default state recovery\n updateRadio($el, true);\n }\n\n if ( typeof(gina.events[evt]) != 'undefined' && gina.events[evt] == $inputs[i].id ) {\n removeListener(gina, $inputs[i], evt);\n proceed($inputs[i], evt);\n } else {\n proceed($inputs[i], evt)\n }\n }\n }\n \n\n evt = 'click';\n\n proceed = function () {\n var subEvent = null;\n // handle form reset\n subEvent = 'reset.'+$target.id;\n if ( typeof(gina.events[subEvent]) == 'undefined' ) {\n addListener(gina, $target, subEvent, function(e) {\n e.preventDefault();\n \n var _id = e.currentTarget.id || e.target.id\n var $form = instance.$forms[_id];\n $form.target.dataset.ginaFormIsResetting = true;\n resetFields($form);\n // forcing it\n var validationInfo = getFormValidationInfos($form.target, $form.rules, true);\n var fields = validationInfo.fields;\n var $fields = validationInfo.$fields; \n \n validate($form.target, fields, $fields, $form.rules, function onSilentResetValidation(result){\n var isFormValid = result.isValid();\n console.debug('silent reset validation result[isValid:'+isFormValid+']: ', result);\n //resetting error display\n handleErrorsDisplay($form.target, {});\n \n updateSubmitTriggerState( $form.target , isFormValid );\n $form.target.dataset.ginaFormIsResetting = false;\n });\n })\n }\n // reset proxy \n addListener(gina, $target, 'reset', function(event) {\n var $el = event.target;\n // prevent event to be triggered twice\n if ( \n typeof(event.defaultPrevented) != 'undefined' \n && event.defaultPrevented \n ) {\n return false;\n }\n // Fixed on 2021/06/08 - because of radio reset\n event.preventDefault();\n \n var _evt = $el.id; \n if (!_evt) return false;\n\n if ( !/^reset\\./.test(_evt) ) {\n _evt = 'reset.'+$el.id\n }\n if (gina.events[_evt]) {\n triggerEvent(gina, $el, _evt, event.detail);\n }\n });\n // keydown proxy \n addListener(gina, $target, 'keydown', function(event) {\n var $el = event.target;\n // prevent event to be triggered twice\n if ( typeof(event.defaultPrevented) != 'undefined' && event.defaultPrevented )\n return false;\n \n keyboardMapping[event.keyCode] = event.type == 'keydown';\n \n var _evt = $el.id; \n if (!_evt) return false;\n\n if ( !/^keydown\\./.test(_evt) ) {\n _evt = 'keydown.'+$el.id\n }\n if (gina.events[_evt]) {\n cancelEvent(event);\n triggerEvent(gina, $el, _evt, event.detail, event);\n }\n });\n // keyup proxy - updating keyboardMapping \n addListener(gina, $target, 'keyup', function(event) {\n var $el = event.target;\n // prevent event to be triggered twice\n if ( typeof(event.defaultPrevented) != 'undefined' && event.defaultPrevented )\n return false;\n \n if (keyboardMapping[event.keyCode]) {\n delete keyboardMapping[event.keyCode]\n }\n \n var _evt = $el.id; \n if (!_evt) return false;\n if ( !/^keyup\\./.test(_evt) ) {\n _evt = 'keyup.'+$el.id\n }\n if (gina.events[_evt]) {\n cancelEvent(event);\n triggerEvent(gina, $el, _evt, event.detail, event);\n }\n });\n \n // focusin proxy \n addListener(gina, $target, 'focusin', function(event) {\n var $el = event.target;\n // prevent event to be triggered twice\n if ( typeof(event.defaultPrevented) != 'undefined' && event.defaultPrevented )\n return false;\n \n var _evt = $el.id; \n if (!_evt) return false;\n\n if ( !/^focusin\\./.test(_evt) ) {\n _evt = 'focusin.'+$el.id\n }\n if (gina.events[_evt]) {\n cancelEvent(event);\n \n triggerEvent(gina, $el, _evt, event.detail);\n }\n });\n // focusout proxy \n addListener(gina, $target, 'focusout', function(event) {\n // Never preventDefault from a proxy listner\n var $el = event.target;\n // prevent event to be triggered twice\n if ( typeof(event.defaultPrevented) != 'undefined' && event.defaultPrevented )\n return false;\n \n var _evt = $el.id; \n if (!_evt) return false;\n\n if ( !/^focusout\\./.test(_evt) ) {\n _evt = 'focusout.'+$el.id\n }\n if (gina.events[_evt]) {\n cancelEvent(event);\n \n triggerEvent(gina, $el, _evt, event.detail);\n }\n }); \n \n // change proxy\n addListener(gina, $target, 'change', function(event) {\n // Never preventDefault from a proxy listner\n var $el = event.target;\n // prevent event to be triggered twice\n if ( typeof(event.defaultPrevented) != 'undefined' && event.defaultPrevented )\n return false;\n \n var _evt = $el.id; \n if (!_evt) return false;\n\n if ( !/^change\\./.test(_evt) ) {\n _evt = 'change.'+$el.id\n }\n if (gina.events[_evt]) {\n cancelEvent(event);\n triggerEvent(gina, $el, _evt, event.detail);\n }\n }); \n // click proxy \n addListener(gina, $target, 'click', function(event) { \n // Never preventDefault from a proxy listner \n var $el = event.target;\n // prevent event to be triggered twice\n // if ( typeof(event.defaultPrevented) != 'undefined' && event.defaultPrevented )\n // return false;\n \n var isCustomSubmit = false, isCaseIgnored = false;\n \n if (\n /(label)/i.test(event.target.tagName) \n && typeof(event.target.control) != 'undefined' \n && event.target.control != null \n && /(checkbox|radio)/i.test(event.target.control.type) \n || \n /(label)/i.test(event.target.parentNode.tagName) \n && typeof(event.target.parentNode.control) != 'undefined' \n && event.target.parentNode.control != null \n && /(checkbox|radio)/i.test(event.target.parentNode.control.type) \n ) { \n var isCaseIgnored = ( \n event.target.getAttribute('for') \n || \n event.target.parentNode.getAttribute('for')\n ) ? true : false\n ; \n // if `event.target.control` not working on all browser,\n // try to detect `for` attribute OR check if on of the label's event.target.children is an input & type == (checkbox|radio)\n $el = event.target.control || event.target.parentNode.control;\n \n }\n if ( \n !$el.disabled \n && /(checkbox|radio)/i.test($el.type) \n && !isCaseIgnored\n ) {\n // apply checked choice : if true -> set to false, and if false -> set to true \n if ( /checkbox/i.test($el.type) ) {\n return updateCheckBox($el);\n } else if ( /radio/i.test($el.type) ) {\n return updateRadio($el, false, true);\n }\n } \n \n \n // include only these elements for the binding\n if ( \n /(button|input)/i.test($el.tagName) && /(submit|checkbox|radio)/i.test($el.type)\n || /a/i.test($el.tagName) && $el.attributes.getNamedItem('data-gina-form-submit')\n // You could also have a click on a child element like <a href=\"#\"><span>click me</span></a>\n || /a/i.test($el.parentNode.tagName) && $el.parentNode.attributes.getNamedItem('data-gina-form-submit')\n ) { \n var namedItem = $el.attributes.getNamedItem('data-gina-form-submit');\n var parentNamedItem = $el.parentNode.attributes.getNamedItem('data-gina-form-submit');\n if (\n namedItem\n ||\n parentNamedItem \n ) { \n isCustomSubmit = true;\n // Get others attribute and override current form attribute \n var newFormMethod = null;\n if (namedItem) {\n newFormMethod = $el.getAttribute('data-gina-form-submit-method');\n } else {\n newFormMethod = $el.parentNode.getAttribute('data-gina-form-submit-method');\n }\n if (newFormMethod) {\n // Backup originalMethod\n \n // Rewrite current method\n if (namedItem && $el.form) {\n $el.form.setAttribute('method', newFormMethod);\n } else if ($el.parentNode.form) {\n $el.parentNode.form.setAttribute('method', newFormMethod);\n }\n }\n }\n \n if ( typeof($el.id) == 'undefined' || !$el.getAttribute('id') ) {\n $el.setAttribute('id', 'click.' + uuid.v4() );\n $el.id = $el.getAttribute('id')\n } else {\n $el.id = $el.getAttribute('id')\n }\n \n \n if (/^click\\./.test($el.id) || withRules) {\n \n var _evt = $el.id;\n \n if (!_evt) return false;\n \n if ( !/^click\\./.test(_evt) ) {\n _evt = $el.id\n }\n \n // normal case\n if (\n !$el.disabled \n && /(checkbox|radio)/i.test($el.type) \n ) {\n //event.stopPropagation(); \n // apply checked choice : if true -> set to false, and if false -> set to true \n if ( /checkbox/i.test($el.type) ) {\n return updateCheckBox($el);\n } else if ( /radio/i.test($el.type) ) {\n return updateRadio($el, false, true);\n }\n }\n \n // prevent event to be triggered twice\n if ( typeof(event.defaultPrevented) != 'undefined' && event.defaultPrevented )\n return false;\n \n // in case we have multiple submit type buttons\n if ( $el.type == 'submit' && !/^submit\\./i.test(_evt) ) {\n _evt = 'submit.'+_evt\n }\n // in case we have multiple reset type buttons\n if ( $el.type == 'reset' && !/^reset\\./i.test(_evt) ) {\n _evt = 'reset.'+_evt\n }\n \n if (gina.events[_evt]) {\n cancelEvent(event);\n \n triggerEvent(gina, $el, _evt, event.detail);\n } else if ( \n isCustomSubmit\n && typeof(this.id) != 'undefined'\n && this.id != ''\n && typeof(gina.validator.$forms[this.id]) != 'undefined'\n ) {\n gina.validator.getFormById(this.id).submit();\n cancelEvent(event); // stop #navigation\n }\n \n }\n } \n\n })\n }\n \n proceed();\n\n \n \n\n\n evt = 'validate.' + _id;\n proceed = function () {\n // attach form submit event\n addListener(gina, $target, evt, function(event) {\n cancelEvent(event);\n \n //var result = event['detail'] || $form.eventData.error || $form.eventData.validation;\n var result = $form.eventData.error || $form.eventData.validation || event['detail'];\n // TODO - Since $form.eventData.error is cached, add a TTL to clear it and allow re $validator.send()\n handleErrorsDisplay(event['target'], result['fields']||result['error'], result['data']);\n\n var _id = event.target.getAttribute('id');\n\n if ( typeof(result['isValid']) != 'undefined' && result['isValid']() ) { // send if valid\n // Experimental - inheritedData\n // Inhertitance from previously posted form: merging datas with current form context\n // TODO - Get the inhereted data from LMDB Database using the form CSRF\n var inheritedData = instance.$forms[_id].target.getAttribute('data-gina-form-inherits-data') || null;\n if (inheritedData) { \n result['data'] = merge(result['data'], JSON.parse(decodeURIComponent(inheritedData)) )\n }\n // now sending to server\n if (instance.$forms[_id]) {\n instance.$forms[_id].send(result['data']);\n } else if ($form) { // just in case the form is being destroyed\n $form.send(result['data']);\n }\n }\n })\n }\n // cannot be binded twice\n if ( typeof(gina.events[evt]) != 'undefined' && gina.events[evt] == 'validate.' + _id ) {\n removeListener(gina, $form, evt, proceed)\n }\n \n proceed();\n\n var proceedToSubmit = function (evt, $submit) {\n // attach submit events\n if ( !/^submit\\./i.test(evt) ) {\n evt = 'submit.'+ evt;\n } \n //console.debug('attaching submit event: `'+ evt +'` on `'+ $submit.id + '` element for form `'+ $submit.form.id +'`');\n addListener(gina, $submit, evt, function(event) {\n // start validation\n cancelEvent(event);\n\n // getting fields & values\n var $fields = {}\n , fields = { '_length': 0 }\n , id = $target.getAttribute('id')\n , rules = ( typeof(instance.$forms[id]) != 'undefined' ) ? instance.$forms[id].rules : null\n , name = null\n , value = 0\n , type = null\n , index = { checkbox: 0, radio: 0 }\n , isDisabled = null \n ;\n \n // stop there if form has already been sent\n if (instance.$forms[id].sent) {\n return;\n }\n \n var validatorInfos = getFormValidationInfos($target, rules);\n fields = validatorInfos.fields;\n $fields = validatorInfos.$fields;\n rules = instance.$forms[id].rules;\n \n\n if ( fields['_length'] == 0 ) { // nothing to validate\n delete fields['_length'];\n var result = {\n 'error' : [],\n 'isValid' : function() { return true },\n 'data' : formatData(fields)\n };\n\n triggerEvent(gina, $target, 'validate.' + _id, result)\n\n } else {\n // update rule in case the current event is triggered outside the main sequence\n // e.g.: form `id` attribute rewritten on the fly\n _id = $target.getAttribute('id');\n var customRule = $target.getAttribute('data-gina-form-rule');\n\n if ( customRule ) { // 'data-gina-form-rule'\n rule = getRuleObjByName(customRule.replace(/\\-|\\//g, '.'))\n } else {\n rule = getRuleObjByName(_id.replace(/\\-/g, '.'))\n }\n instance.$forms[id].isSubmitting = true;\n instance.$forms[id].isSending = false;\n validate($target, fields, $fields, rule, function onClickValidation(result){\n triggerEvent(gina, $target, 'validate.' + _id, result)\n })\n }\n });\n }\n\n\n // BO binding submit button\n var $submit = null\n , $buttons = []\n , $buttonsTMP = []\n , linkId = null \n , buttonId = null\n ;\n $buttonsTMP = $target.getElementsByTagName('button');\n if ( $buttonsTMP.length > 0 ) {\n for(let b = 0, len = $buttonsTMP.length; b < len; ++b) {\n if ($buttonsTMP[b].type == 'submit') {\n $buttons.push($buttonsTMP[b])\n } \n }\n }\n\n // binding links\n $buttonsTMP = $target.getElementsByTagName('a'); \n if ( $buttonsTMP.length > 0 ) {\n for(let b = 0, len = $buttonsTMP.length; b < len; ++b) {\n if ( $buttonsTMP[b].attributes.getNamedItem('data-gina-form-submit') ) {\n $buttons.push($buttonsTMP[b])\n } else if ( \n !$buttonsTMP[b].getAttribute('id') \n && !/gina\\-popin/.test($buttonsTMP[b].className) \n && !gina.popinIsBinded\n && !/gina\\-link/.test($buttonsTMP[b].className) \n ) { // will not be binded but will receive an id if not existing\n linkId = 'link.'+ uuid.v4();\n $buttonsTMP[b].id = linkId;\n }\n }\n }\n\n // \n var onclickAttribute = null, isSubmitType = false;\n for (let b=0, len=$buttons.length; b<len; ++b) {\n\n $submit = $buttons[b];\n // retrieve submitTrigger\n if (\n /button/i.test($submit.tagName) \n && typeof($submit.type) != 'undefined'\n && /submit/i.test($submit.type)\n ||\n /a/i.test($submit.tagName) \n && typeof($submit.dataset.ginaFormSubmit) != 'undefined'\n && /^true$/i.test($submit.dataset.ginaFormSubmit)\n ||\n /a/i.test($submit.parentNode.tagName)\n && typeof($submit.parentNode.dataset.ginaFormSubmit) != 'undefined'\n && /^true$/i.test($submit.parentNode.dataset.ginaFormSubmit)\n ) {\n if ( /a/i.test($submit.parentNode.tagName) ) {\n $submit = $submit.parentNode;\n }\n \n if ( typeof($submit.id) == 'undefined' || typeof($submit.id) != 'undefined' && $submit.id == \"\" ) {\n $submit.id = 'click.'+uuid.v4();\n $submit.setAttribute('id', $submit.id);\n }\n \n if ( /a/i.test($submit.tagName) && typeof($submit.form) == 'undefined' ) {\n $submit.form = { id: $form.id };\n }\n \n /**if ( typeof(instance.$forms[$form.id].submitTrigger) != 'undefined' && $submit.form.id !== instance.$forms[$form.id].submitTrigger ) {\n console.warn('Form `submitTrigger` is already defined for your form #'+ $submit.form.id +': cannot attach `'+$submit.id+'`');\n } else */\n if (\n typeof($submit.dataset.ginaFormSubmitTriggerFor) == 'undefined'\n && typeof(instance.$forms[$form.id]) != 'undefined'\n && typeof(instance.$forms[$form.id].submitTrigger) == 'undefined' \n && typeof($submit.form.id) != 'undefined'\n && $form.id == $submit.form.id\n ) {\n console.debug('attching submitTrigger: '+ $submit.id, ' \\ form id: '+ $form.id);\n instance.$forms[$form.id].submitTrigger = $form.submitTrigger = $submit.id || $submit.getAttribute('id');\n // mark submitTrigger\n $submit.dataset.ginaFormSubmitTriggerFor = $form.id;\n } // else, skipping\n }\n\n if ($submit.tagName == 'A') { // without this test, XHR callback is ignored\n //console.debug('a#$buttons ', $buttonsTMP[b]);\n onclickAttribute = $submit.getAttribute('onclick');\n isSubmitType = $submit.getAttribute('data-gina-form-submit');\n\n if ( !onclickAttribute && !isSubmitType) {\n $submit.setAttribute('onclick', 'return false;')\n } else if ( !/return false/i.test(onclickAttribute) && !isSubmitType) {\n if ( /\\;$/.test(onclickAttribute) ) {\n onclickAttribute += 'return false;'\n } else {\n onclickAttribute += '; return false;'\n }\n }\n }\n\n if (!$submit['id']) {\n evt = 'click.'+ uuid.v4();\n $submit['id'] = evt;\n $submit.setAttribute( 'id', evt);\n } else {\n evt = $submit['id'];\n }\n \n if ( typeof(gina.events[evt]) == 'undefined' || gina.events[evt] != $submit.id ) {\n proceedToSubmit(evt, $submit)\n }\n\n }// BO binding submit button\n\n evt = 'submit';\n \n // submit proxy\n addListener(gina, $target, evt, function(e) {\n\n var $target = e.target\n , id = $target.getAttribute('id')\n , $formInstance = instance.$forms[id]\n , isBinded = $form.binded\n ;\n \n // check submit trigger status\n var submitTrigger = new DOMParser()\n .parseFromString($target.innerHTML, 'text/html')\n .getElementById($formInstance.submitTrigger);\n // prevent submit if disabled\n if ( submitTrigger && submitTrigger.disabled) {\n cancelEvent(e);\n }\n\n // prevent event to be triggered twice\n if ( typeof(e.defaultPrevented) != 'undefined' && e.defaultPrevented )\n return false;\n\n if (withRules || isBinded) {\n cancelEvent(e);\n }\n\n\n // just collect data over forms\n // getting fields & values\n var $fields = {}\n , fields = { '_length': 0 }\n , id = $target.getAttribute('id')\n , rules = ( typeof(gina.validator.$forms[id]) != 'undefined' ) ? gina.validator.$forms[id].rules : null\n , name = null\n , value = 0\n , type = null\n , index = { checkbox: 0, radio: 0 }\n , isDisabled = null \n ;\n\n\n for (var i = 0, len = $target.length; i<len; ++i) {\n \n name = $target[i].getAttribute('name');\n // NB.: If you still want to save the info and you main field is disabled;\n // consider using an input type=hidden of validator rule `\"exclude\" : false`\n isDisabled = $target[i].disabled || $target[i].getAttribute('disabled'); \n isDisabled = ( /disabled|true/i.test(isDisabled) ) ? true : false;\n\n if (!name) continue;\n if (isDisabled) continue;\n\n // checkbox or radio\n if ( typeof($target[i].type) != 'undefined' && $target[i].type == 'radio' || typeof($target[i].type) != 'undefined' && $target[i].type == 'checkbox' ) {\n\n if ( $target[i].checked ) {\n // if is boolean\n if ( /^(true|false)$/.test($target[i].value) ) {\n fields[name] = $target[i].value = (/^true$/.test($target[i].value)) ? true : false\n } else {\n fields[name] = $target[i].value\n }\n\n } else if ( // force validator to pass `false` if boolean is required explicitly\n rules\n && typeof(rules[name]) != 'undefined'\n && typeof (rules[name].isBoolean) != 'undefined' && $target[i].type == 'checkbox'\n //&& typeof(rules[name].isRequired) != 'undefined'\n && !/^(true|false)$/.test($target[i].value)\n ) {\n fields[name] = false;\n }\n\n } else {\n fields[name] = $target[i].value;\n }\n\n\n\n $fields[name] = $target[i];\n // reset filed error data attributes\n $fields[name].setAttribute('data-gina-form-errors', '');\n\n //++fields['_length']\n }\n fields['_length'] = fields.count();\n\n\n if ( fields['_length'] == 0 ) { // nothing to validate\n\n delete fields['_length'];\n var result = {\n 'error' : [],\n 'isValid' : function() { return true },\n 'data' : formatData(fields)\n };\n\n if ( typeof(gina.events['submit.' + id]) != 'undefined' ) { // if `on('submit', cb)` is binded\n triggerEvent(gina, $target, 'submit.' + id, result);\n } else {\n triggerEvent(gina, $target, 'validate.' + id, result);\n }\n\n } else {\n // update rule in case the current event is triggered outside the main sequence\n // e.g.: form `id` attribute rewritten on the fly\n var customRule = $target.getAttribute('data-gina-form-rule');\n\n if ( customRule ) { // 'data-gina-form-rule'\n rule = getRuleObjByName(customRule.replace(/\\-|\\//g, '.'))\n } else {\n rule = getRuleObjByName(id.replace(/\\-/g, '.'))\n }\n instance.$forms[id].isValidating = true;\n validate($target, fields, $fields, rule, function onSubmitValidation(result){\n instance.$forms[id].isValidating = false;\n // var isFormValid = result.isValid();\n // if (isFormValid) {\n // //resetting error display\n // handleErrorsDisplay($target, {}, result.data);\n // } else { \n // handleErrorsDisplay($target, result.error, result.data);\n if ( typeof(gina.events['submit.' + id]) != 'undefined' ) { // if `on('submit', cb)` is binded\n triggerEvent(gina, $target, 'submit.' + id, result);\n } else {\n triggerEvent(gina, $target, 'validate.' + id, result);\n }\n return;\n // }\n })\n }\n });\n \n \n \n instance.$forms[_id]['binded'] = true; \n // If Live check enabled, proceed to silent validation\n if ( /^(true)$/i.test($form.target.dataset.ginaFormLiveCheckEnabled && $form.rules.count() > 0) ) {\n console.debug('silent validation mode on');\n var validationInfo = getFormValidationInfos($form.target, $form.rules);\n var fields = validationInfo.fields;\n var $fields = validationInfo.$fields;\n validate($form.target, fields, $fields, $form.rules, function onSilentValidation(result){ \n console.debug('silent validation result[isValid:'+result.isValid()+']: ', result);\n if ( envIsDev && isGFFCtx && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar ) {\n // update toolbar\n if (!gina.forms.errors)\n gina.forms.errors = {};\n \n var objCallback = {\n id : _id,\n errors : result.error //,\n // we might also need to update rules in case of form ajax changes\n // rules : $form.rules,\n // data : result.data\n };\n \n window.ginaToolbar.update('forms', objCallback);\n }\n updateSubmitTriggerState( $form, result.isValid() );\n });\n } else if (!/^(true)$/i.test($form.target.dataset.ginaFormLiveCheckEnabled) ) {\n updateSubmitTriggerState( $form , true );\n }\n \n } // EO bindForm()\n \n var updateSubmitTriggerState = function($formInstanceOrTarget, isFormValid) {\n //console.debug('submitTrigger[isFormValid='+ isFormValid +']: ', $formInstance.submitTrigger)\n $formInstance = null;\n if ( $formInstanceOrTarget instanceof HTMLFormElement ) { // is target DOMobject\n var id = $formInstanceOrTarget.getAttribute('id');\n $formInstance = instance.$forms[id];\n } else {\n $formInstance = $formInstanceOrTarget;\n }\n //if (!$formInstance) return;\n \n if ( typeof($formInstance.submitTrigger) == 'undefined') {\n console.warn('This might be normal, so do not worry if this form is handled by your javascript: `'+ $formInstance.id +'`\\nGina could not complete `updateSubmitTriggerState()`: `submitTrigger` might not be attached to form instance `'+ $formInstance.id +'`\\nTo disable this warning, You just need to disable `Form Live Checking on your form by adding to your <form>: `data-gina-form-live-check-enabled=false``')\n } else if ( document.getElementById($formInstance.submitTrigger) ) {\n if ( /true/i.test(isFormValid) ) { // show submitTrigge\n document.getElementById($formInstance.submitTrigger).disabled = false;\n } else { // hide submitTrigger\n document.getElementById($formInstance.submitTrigger).disabled = true;\n }\n }\n }\n \n /**\n * getFormValidationInfos\n * \n * @param {object} $form - form target (DOMObject), not the instance\n * @param {object} [rules]\n * \n * @returns {object} { .fields, .$fields, .rules }\n */\n var getFormValidationInfos = function($form, rules, isOnResetMode) {\n // patching form reset\n if (typeof(isOnResetMode) == 'undefined') {\n isOnResetMode = false;\n }\n // getting fields & values\n var $fields = {}\n , fields = {}//{ '_length': 0 }\n , id = $form.id || $form.getAttribute('id')\n , name = null\n , value = 0\n , type = null\n , index = { checkbox: 0, radio: 0 }\n , isDisabled = null\n ;\n if ( typeof(rules) == 'undefined' ) {\n rules = ( typeof(instance.$forms[id].rules) != 'undefined' && instance.$forms[id].rules.count() > 0 ) ? instance.$forms[id].rules : null;\n if (!rules && typeof(gina.validator.$forms[id]) != 'undefined') {\n rules = gina.validator.$forms[id].rules\n }\n }\n\n // BO Parsing form elements\n for (var i = 0, len = $form.length; i<len; ++i) { \n if ( isOnResetMode ) {\n // reset form values\n switch ($form[i].tagName.toLowerCase()) {\n case 'input':\n if ( /^(hidden|text)$/i.test($form[i].type) ) {\n $form[i].value = $form[i].defaultValue;\n }\n break;\n \n default:\n break;\n }\n }\n \n // retrieve submitTrigger\n if (\n /button/i.test($form[i].tagName) \n && typeof($form[i].type) != 'undefined'\n && /submit/i.test($form[i].type)\n ||\n /a/i.test($form[i].tagName) \n && typeof($form[i].dataset.ginaFormSubmit) != 'undefined'\n && /^true$/i.test($form[i].dataset.ginaFormSubmit)\n ) {\n if ( /a/i.test($form[i].tagName) && typeof($form[i].form) == 'undefined' ) {\n $form[i].form = { id: id };\n }\n /**if ( typeof(instance.$forms[id].submitTrigger) != 'undefined' && $form[i].form.id !== instance.$forms[id].submitTrigger ) {\n console.warn('Form `submitTrigger` is already defined for your form `#'+ $form[i].form.id +'`: cannot attach `'+$form[i].id+'`');\n } else */\n if ( \n typeof($form[i].dataset.ginaFormSubmitTriggerFor) == 'undefined'\n && typeof(instance.$forms[id]) != 'undefined'\n && typeof(instance.$forms[id].submitTrigger) == 'undefined'\n && typeof($form[i].form.id) != 'undefined' \n && id == $form[i].form.id\n ) {\n instance.$forms[id].submitTrigger = $form[i].id || $form[i].getAttribute('id');\n // mark submitTrigger\n $form[i].dataset.ginaFormSubmitTriggerFor = id;\n } \n // else, skipping\n }\n \n name = $form[i].getAttribute('name');\n // NB.: If you still want to save the info and you main field is disabled;\n // consider using an input type=hidden of validator rule `\"exclude\" : false`\n isDisabled = $form[i].disabled || $form[i].getAttribute('disabled'); \n isDisabled = ( /disabled|true/i.test(isDisabled) ) ? true : false;\n \n if (!name) continue;\n if (isDisabled) continue;\n\n // TODO - add switch cases against tagName (checkbox/radio)\n if ( \n typeof($form[i].type) != 'undefined'\n && $form[i].type == 'radio' \n || \n typeof($form[i].type) != 'undefined'\n && $form[i].type == 'checkbox' )\n {\n \n if ( \n $form[i].checked \n || typeof (rules[name]) == 'undefined'\n && $form[i].value != 'undefined'\n && /^(true|false)$/.test($form[i].value)\n || !$form[i].checked\n && typeof (rules[name]) != 'undefined'\n //&& typeof (rules[name].isBoolean) != 'undefined' && /^true$/.test(rules[name].isBoolean)\n //&& typeof (rules[name].isRequired) != 'undefined' && /^true$/.test(rules[name].isRequired)\n && typeof (rules[name].isBoolean) != 'undefined'\n && /^(true|false)$/.test($form[i].value)\n ) {\n // if is boolean\n if ( /^(true|false)$/.test($form[i].value) ) {\n \n if ( typeof(rules[name]) == 'undefined' ) {\n rules[name] = { isBoolean: true };\n } else if ( typeof(rules[name]) != 'undefined' && typeof(rules[name].isBoolean) == 'undefined' ) {\n rules[name].isBoolean = true;\n // forces it when field found in validation rules\n rules[name].isRequired = true;\n }\n\n if ($form[i].type == 'radio') {\n if ( typeof(rules[name]) == 'undefined' )\n throw new Error('rule '+ name +' is not defined');\n \n if (/^true$/.test(rules[name].isBoolean) && $form[i].checked ) {\n fields[name] = (/^true$/.test($form[i].value)) ? true : false;\n }\n } else {\n fields[name] = $form[i].value = (/^true$/.test($form[i].value)) ? true : false;\n }\n\n } else {\n fields[name] = $form[i].value\n }\n \n } else if ( // force validator to pass `false` if boolean is required explicitly\n rules\n && typeof(rules[name]) != 'undefined'\n && typeof(rules[name].isBoolean) != 'undefined'\n && typeof(rules[name].isRequired) != 'undefined'\n && !/^(true|false)$/.test($form[i].value)\n\n ) {\n fields[name] = false;\n }\n\n } else {\n fields[name] = $form[i].value;\n }\n\n if ( typeof($fields[name]) == 'undefined' ) {\n $fields[name] = $form[i];\n // reset filed error data attributes\n $fields[name].setAttribute('data-gina-form-errors', '');\n }\n \n //++fields['_length']\n }// EO Parsing form elements\n fields['_length'] = fields.count() || 0;\n \n return {\n '$fields' : $fields,\n 'fields' : fields,\n 'rules' : rules\n }\n }\n \n var getCastedValue = function(ruleObj, fields, fieldName, isOnDynamisedRulesMode) {\n \n if ( \n // do not cast if no rule linked to the field\n typeof(ruleObj[fieldName]) == 'undefined'\n // do not cast if not defined or on error\n || /^(null|NaN|undefined|\\s*)$/i.test(fields[fieldName])\n ) {\n return fields[fieldName]\n }\n \n if ( \n /**typeof(ruleObj[fieldName].isBoolean) != 'undefined'\n || */typeof(ruleObj[fieldName].isNumber) != 'undefined'\n || typeof(ruleObj[fieldName].isInteger) != 'undefined'\n || typeof(ruleObj[fieldName].isFloat) != 'undefined'\n || typeof(ruleObj[fieldName].toFloat) != 'undefined'\n || typeof(ruleObj[fieldName].toInteger) != 'undefined'\n ) {\n \n if ( /\\,/.test(fields[fieldName]) ) {\n fields[fieldName] = fields[fieldName].replace(/\\,/g, '.').replace(/\\s+/g, '');\n }\n return fields[fieldName];\n }\n \n if ( typeof(fields[fieldName]) == 'boolean') {\n return fields[fieldName]\n } else if (ruleObj[fieldName].isBoolean) {\n return (/^true$/i.test(fields[fieldName])) ? true : false;\n }\n \n return (\n typeof(isOnDynamisedRulesMode) != 'undefined' \n && /^true$/i.test(isOnDynamisedRulesMode) \n ) ? '\\\\\"'+ fields[fieldName] +'\\\\\"' : fields[fieldName];\n }\n \n /**\n * formatFields\n * Will cast values if needed\n * \n * @param {string|object} rules \n * @param {object} fields \n * @returns \n */\n var formatFields = function(rules, fields) {\n var ruleObj = null;\n if ( typeof(rules) != 'string') {\n rules = JSON.stringify(JSON.clone(rules))\n }\n ruleObj = JSON.parse(rules.replace(/\\\"(true|false)\\\"/gi, '$1'));\n \n for (let fName in fields) {\n fields[fName] = getCastedValue(ruleObj, fields, fName);\n }\n return fields;\n }\n \n var getDynamisedRules = function(stringifiedRules, fields, $fields, isLiveCheckingOnASingleElement) {\n \n // Because this could also be live check, if it is the case, we need all fields\n // of the current form rule for variables replacement/evaluation. Since live check is\n // meant to validate one field at the time, you could fall in a case where the current\n // field should be compared with another field of the same form.\n var ruleObj = JSON.parse(stringifiedRules.replace(/\\\"(true|false)\\\"/gi, '$1'));\n var stringifiedRulesTmp = JSON.stringify(ruleObj);\n if (isLiveCheckingOnASingleElement) { \n var $currentForm = $fields[Object.getOwnPropertyNames($fields)[0]].form;\n var vInfos = getFormValidationInfos($currentForm, ruleObj);\n delete vInfos.fields._length;\n \n fields = vInfos.fields;\n $fields = vInfos.$fields;\n }\n \n \n var re = null, _field = null, arrFields = [], a = 0;\n // avoiding conflict like [\"myfield\", \"myfield-name\"]\n // where once `myfield` is replaced for exemple with `1234`, you also get 1234-name left behind\n // TODO - Replace this trick with a RegExp matching only the exact word\n // TODO - test this one: \n // \\W(\\$myfield-name)(?!-)\\W\n for (let field in fields) {\n arrFields[a] = field;\n a++;\n }\n arrFields.sort().reverse();\n \n for (let i = 0, len = arrFields.length; i < len; i++) {\n _field = arrFields[i].replace(/\\-|\\_|\\@|\\#|\\.|\\[|\\]/g, '\\\\$&');\n re = new RegExp('\\\\$'+_field, 'g');\n // default field value\n let fieldValue = '\\\\\"'+ fields[arrFields[i]] +'\\\\\"';\n let isInRule = re.test(stringifiedRulesTmp);\n if ( isInRule && typeof(ruleObj[arrFields[i]]) != 'undefined' ) {\n fieldValue = getCastedValue(ruleObj, fields, arrFields[i], true);\n } else if ( isInRule ) {\n console.warn('`'+arrFields[i]+'` is used in a dynamic rule without definition. This could lead to an evaluation error. Casting `'+arrFields[i]+'` to `string`.');\n }\n \n stringifiedRules = stringifiedRules.replace(re, fieldValue );\n }\n if ( /\\$(.*)/.test(stringifiedRules) ) {\n for (let i = 0, len = arrFields.length; i < len; i++) {\n _field = arrFields[i].replace(/\\-|\\_|\\@|\\#|\\.|\\[|\\]/g, '\\\\$&');\n re = new RegExp('\\\\$'+_field, 'g');\n // default field value\n let fieldValue = ($fields[arrFields[i]].value != '' ) ? '\\\\\"'+ $fields[arrFields[i]].value +'\\\\\"' : '\\\\\"\\\\\"';\n let isInRule = re.test(stringifiedRulesTmp);\n if ( isInRule && typeof(ruleObj[arrFields[i]]) != 'undefined' ) {\n fieldValue = getCastedValue(ruleObj, fields, arrFields[i], true);\n } else if ( isInRule ) {\n console.warn('`'+arrFields[i]+'` is used in a dynamic rule without definition. This could lead to an evaluation error. Casting `'+arrFields[i]+'` to `string`.');\n }\n \n stringifiedRules = stringifiedRules.replace(re, fieldValue || $fields[arrFields[i]].checked);\n }\n }\n \n return JSON.parse(stringifiedRules)\n }\n \n \n /**\n * Validate form\n * @param {object} $formOrElement - ${form|element}.target (DOMObject)\n * @param {object} fields \n * @param {object} $fields \n * @param {object} rules \n * @param {callback} cb \n */\n var validate = function($formOrElement, fields, $fields, rules, cb) {\n\n delete fields['_length']; //cleaning\n \n var stringifiedRules = JSON.stringify(rules);\n fields = formatFields(stringifiedRules, fields);\n if ( /\\$(.*)/.test(stringifiedRules) ) {\n var isLiveCheckingOnASingleElement = (\n !/^form$/i.test($formOrElement.tagName)\n && $fields.count() == 1\n && /true/i.test($formOrElement.form.dataset.ginaFormLiveCheckEnabled)\n ) ? true : false;\n rules = getDynamisedRules(stringifiedRules, fields, $fields, isLiveCheckingOnASingleElement)\n }\n var id = null\n , evt = null\n , data = null\n , hasBeenValidated = false\n , subLevelRules = 0\n , rootFieldsCount = fields.count()\n , hasParsedAllRules = false \n , $asyncField = null\n , $asyncFieldId = null\n , asyncEvt = null\n , asyncCount = 0\n ;\n \n \n var re = null, flags = null, args = null; \n var checkFieldAgainstRules = function(field, rules, fields) {\n // ignore field if used as a _case_field\n \n // looking for regexp aliases from rules\n if ( typeof (rules[field]) == 'undefined') { \n skipTest = false;\n // TODO - replace loop by checkForRuleAlias(rules, $el);\n for (var _r in rules) {\n if (/^_comment$/i.test(_r)) continue;\n if ( /^\\//.test(_r) ) { // RegExp found\n re = _r.match(/\\/(.*)\\//).pop(); \n flags = _r.replace('/'+ re +'/', '');\n // fix escaping \"[\" & \"]\"\n re = re.replace(/\\[/g, '\\\\[').replace(/\\]/g, '\\\\]');\n re = new RegExp(re, flags);\n if ( re.test(field) ) { \n skipTest = true; \n // create new entry \n rules[field] = rules[_r]; \n break;\n } \n } \n }\n \n if ( typeof(rules[field]) == 'undefined' )\n return;\n }\n \n var listedFields = Object.getOwnPropertyNames(rules) || [];\n var f = 0, fLen = listedFields.length;\n if (fLen > 0) {\n while (f < fLen) {\n if ( \n typeof(rules[listedFields[f]].exclude) != 'undefined'\n && /^true$/i.test(rules[listedFields[f]].exclude) \n ) {\n // remove from listedFields\n listedFields.splice(f, 1);\n fLen--;\n f--;\n }\n f++;\n }\n }\n \n // check each field against rule\n for (var rule in rules[field]) {\n // skip when not processing rule function\n if ( typeof(d[field][rule]) != 'function' ) {\n continue;\n }\n \n if ( /^((is)\\d+|is$)/.test(rule) && typeof(d[field][rule]) == 'undefined' ) { // is aliases \n d[field][rule] = function(){};\n d[field][rule] = inherits(d[field][rule], d[field][ rule.replace(/\\d+/, '') ]);\n d[field][rule].setAlias = (function(alias) {\n this._currentValidatorAlias = alias\n }(rule)); \n } \n // check for rule params\n try {\n if (Array.isArray(rules[field][rule])) { // has args\n //convert array to arguments\n args = JSON.clone(rules[field][rule]);\n if ( /\\$[\\-\\w\\[\\]]*/.test(args[0]) ) {\n var foundVariables = args[0].match(/\\$[\\-\\w\\[\\]]*/g);\n for (var v = 0, vLen = foundVariables.length; v < vLen; ++v) {\n args[0] = args[0].replace( foundVariables[v], d[foundVariables[v].replace('$', '')].value )\n }\n }\n d[field][rule].apply(d[field], args);\n } else {\n // query rule case\n if ( /^query$/.test(rule) ) {\n $asyncField = $fields[field];\n $asyncFieldId = $asyncField.getAttribute('id');\n asyncEvt = 'asyncCompleted.'+ $asyncFieldId;\n \n var triggeredCount = 0, eventTriggered = false;\n if ( typeof(gina.events[asyncEvt]) != 'undefined' ) { \n console.debug('event `'+ asyncEvt +'` already added');\n asyncCount = 0;\n return;\n }\n ++asyncCount;\n //console.debug('Adding listner '+asyncEvt);\n addListener(gina, $asyncField, asyncEvt, function onasyncCompleted(event) {\n event.preventDefault();\n \n triggeredCount++; \n --asyncCount;\n // is this the last rule ?\n var _rulesArr = Object.getOwnPropertyNames(rules[field]);\n if (_rulesArr[_rulesArr.length-1] == rule) {\n hasParsedAllRules = true;\n }\n \n var _asyncEvt = 'asyncCompleted.' + event.target.getAttribute('id');\n if ( /true/.test(eventTriggered) ) {\n // console.debug('already triggered !\\nasyncCount: '+ asyncCount +'\\nhasParsedAllRules: '+hasParsedAllRules ); \n return;\n }\n \n d[field] = event.detail;\n \n // retrieve current form\n var $currentForm = $formOrElement;\n if ( !/^form$/i.test($formOrElement.tagName) ) {\n $currentForm = $formOrElement.form; \n } \n var formId = $currentForm.getAttribute('id');\n \n if ( \n hasParsedAllRules \n && asyncCount <= 0\n && !eventTriggered\n ) {\n eventTriggered = true;\n \n // removing listner to revalidate with another context\n //console.debug('removing listner '+ _asyncEvt +'\\nasyncCount: '+ asyncCount +'\\nhasParsedAllRules: '+hasParsedAllRules + '\\neventTriggered: '+ eventTriggered);\n removeListener(gina, event.target, _asyncEvt);\n \n cb._data = d['toData']();\n cb._errors = d['getErrors'](field);\n // console.debug('query callbakc triggered ', cb._errors, '\\nisValidating: ', instance.$forms[formId].isValidating);\n // update instance form errors\n if ( cb._errors && cb._errors.count() > 0) {\n if ( typeof(instance.$forms[formId].errors) == 'undefined' ) {\n instance.$forms[formId].errors = {}\n }\n \n instance.$forms[formId].errors[field] = cb._errors[field];\n \n if (!isFormValid && /^true|false$/i.test(instance.$forms[formId].isValidating) || d[field].target.value != '' ) { \n refreshWarning($allFields[field]);\n handleErrorsDisplay($currentForm, cb._errors, cb._data, field);\n updateSubmitTriggerState( $currentForm, isFormValid);\n }\n \n if ( envIsDev && isGFFCtx && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar ) {\n // update toolbar\n if (!gina.forms.errors)\n gina.forms.errors = {};\n \n var objCallback = {\n id : formId,\n errors : instance.$forms[formId].errors || {}\n };\n \n window.ginaToolbar.update('forms', objCallback);\n }\n \n \n triggerEvent(gina, $currentForm, 'validated.' + formId, cb);\n return;\n } \n }\n \n // is this the last or the only field to be validated ?\n var needsGlobalReValidation = false, isFormValid = null;\n if ( listedFields.length == 1 || listedFields[listedFields.length-1] == field) {\n // trigger end of validation\n // console.debug(field +' is the last element to be validated for formId: '+ formId, cb._errors, instance.$forms[formId].errors);\n isFormValid = ( cb._errors.count() > 0 ) ? false : true;\n if (!isFormValid && /^true|false$/i.test(instance.$forms[formId].isValidating)) {\n //console.debug('should update error display now ', cb._errors);\n instance.$forms[formId].errors = merge(cb._errors, instance.$forms[formId].errors);\n refreshWarning($allFields[field]);\n handleErrorsDisplay($currentForm, cb._errors, cb._data, field);\n updateSubmitTriggerState( $currentForm, isFormValid);\n } \n triggerEvent(gina, $currentForm, 'validated.' + formId, cb);\n }\n // just update warning state \n else if (/^true$/i.test(instance.$forms[formId].isValidating) && listedFields.length > 1 && listedFields[listedFields.length-1] != field ) {\n //console.debug(field +' is NOT the last element to be validated for formId: '+ formId);\n needsGlobalReValidation = true; \n }\n \n if (needsGlobalReValidation) {\n validate($currentForm, allFields, $allFields, rules, function onSilentQueryGlobalLiveValidation(gResult){\n instance.$forms[formId].isValidating = false;\n // console.debug('['+ formId +'] onSilentQueryGlobalLiveValidation: '+ gResult.isValid(), gResult);\n isFormValid = gResult.isValid();\n if ( envIsDev && isGFFCtx && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar ) {\n // update toolbar\n if (!gina.forms.errors)\n gina.forms.errors = {};\n \n var objCallback = {\n id : formId,\n errors : gResult.error || {}\n };\n \n window.ginaToolbar.update('forms', objCallback);\n } \n \n \n \n handleErrorsDisplay($currentForm, gResult.error, gResult.data, field);\n updateSubmitTriggerState( $currentForm, isFormValid);\n })\n }\n \n });\n \n d[field][rule](rules[field][rule]);\n continue;\n }\n // normal rule case\n else {\n d[field][rule](rules[field][rule]);\n }\n }\n\n delete fields[field];\n\n } catch (err) {\n if (rule == 'conditions') {\n throw new Error('[ ginaFormValidator ] could not evaluate `' + field + '->' + rule + '()` where `conditions` must be a `collection` (Array)\\nStack:\\n' + err)\n } else {\n throw new Error('[ ginaFormValidator ] could not evaluate `' + field + '->' + rule + '()`\\nStack:\\n' + err)\n }\n }\n }\n }\n \n \n //console.debug(fields, $fields);\n var d = null;//FormValidator instance\n var fieldErrorsAttributes = {}, isSingleElement = false;\n if (isGFFCtx) { // Live check if frontend only for now\n // form case\n if ( /^form$/i.test($formOrElement.tagName) ) {\n id = $formOrElement.getAttribute('id');\n evt = 'validated.' + id;\n instance.$forms[id].fields = fields;\n // clear existing errors\n if ( typeof($formOrElement.eventData) != 'undefined' && typeof($formOrElement.eventData.error) != 'undefined' ) {\n delete $formOrElement.eventData.error\n }\n d = new FormValidator(fields, $fields, xhrOptions);\n }\n // single element case \n else {\n isSingleElement = true;\n id = $formOrElement.form.getAttribute('id') || $formOrElement.form.target.getAttribute('id');\n \n evt = 'validated.' + id;\n instance.$forms[id].fields = fields;\n d = new FormValidator(fields, $fields, xhrOptions, instance.$forms[id].fieldsSet); \n } \n } else {\n d = new FormValidator(fields, null, xhrOptions);\n }\n\n \n var allFields = null;\n var $allFields = null;\n if (!isSingleElement) {\n allFields = JSON.clone(fields);\n $allFields = $fields;\n } else {\n // TODO - Get cached infos\n var formId = $formOrElement.form.getAttribute('id');\n var formAllInfos = getFormValidationInfos(instance.$forms[formId].target, instance.$forms[formId].rules, false); \n allFields = formatFields(JSON.stringify(instance.$forms[formId].rules), JSON.clone(formAllInfos.fields));\n $allFields = formAllInfos.$fields;\n }\n \n var allRules = ( typeof(rules) != 'undefined' ) ? JSON.clone(rules) : {};\n var forEachField = function($formOrElement, allFields, allRules, fields, $fields, rules, cb, i) { \n \n \n var hasCase = false, isInCase = null, conditions = null;\n var caseValue = null, caseType = null;\n var localRules = null, caseName = null;\n var localRuleObj = null, skipTest = null;\n\n //console.debug('parsing ', fields, $fields, rules);\n if ( typeof(rules) != 'undefined' ) {\n \n for (var field in fields) {\n \n if ( isGFFCtx && typeof($fields[field]) == 'undefined' ) {\n //throw new Error('field `'+ field +'` found for your form rule ('+ $formOrElement.id +'), but not found in $field collection.\\nPlease, check your HTML or remove `'+ field +'` declaration from your rule.')\n console.warn('field `'+ field +'` found for your form rule ('+ $formOrElement.id +'), but not found in $field collection.\\nPlease, check your HTML or remove `'+ field +'` declaration from your rule if this is a mistake.');\n continue;\n }\n // 2021-01-17: fixing exclude default override for `data-gina-form-element-group`\n if ( \n isGFFCtx\n && $fields[field].getAttribute('data-gina-form-element-group')\n && typeof(rules[field]) != 'undefined'\n && typeof(rules[field].exclude) != 'undefined'\n && rules[field].exclude\n && !$fields[field].disabled\n ) {\n rules[field].exclude = false;\n }\n \n hasCase = ( typeof(rules['_case_' + field]) != 'undefined' ) ? true : false;\n isInCase = false;\n \n \n if ( \n isGFFCtx\n && $fields[field].tagName.toLowerCase() == 'input' \n && /(checkbox)/i.test($fields[field].getAttribute('type')) \n ) {\n if ( \n !$fields[field].checked\n && typeof(rules[field]) != 'undefined' \n && typeof(rules[field].isRequired) != 'undefined' \n && /^(false)$/i.test(rules[field].isRequired)\n ||\n $fields[field].disabled\n ) { \n rules[field] = {\n exclude: true\n } \n \n } else if ( !$fields[field].checked && typeof(rules[field]) == 'undefined' ) { \n continue;\n }\n }\n \n\n \n \n for (var c in rules) {\n if (!/^\\_case\\_/.test(c) ) continue;\n if ( typeof(rules[c].conditions) == 'undefined' || Array.isArray(rules[c].conditions) && !rules[c].conditions.length ) continue;\n if ( typeof(rules[c].conditions[0].rules) == 'undefined' ) continue;\n \n \n // enter cases conditions\n if ( \n typeof(rules[c].conditions) != 'undefined' \n && Array.isArray(rules[c].conditions) \n ) {\n caseName = c.replace('_case_', ''); \n // if case exists but case field not existing\n if ( typeof($allFields[caseName]) == 'undefined' ) {\n console.warn('Found case `'+ c +'` but field `'+ caseName +'` is misssing in the dom.\\n You should add `'+ caseName +'` element to your form in order to allow Validator to process this case.');\n continue\n }\n \n // depending on the case value, replace/merge original rule with condition rule\n if ( typeof(allFields[caseName]) == 'undefined' ) {\n //allFields[caseName] = $fields[c.replace(/^\\_case\\_/, '')].value\n allFields[caseName] = $allFields[caseName].value\n }\n // Watch changes in case the value is modified\n // A mutation observer was previously defined in case of hidden field when value has been mutated with javascript\n // Ref.: liveCheck; look for comment `// Adding observer for hidden fileds`\n /**\n let caseEvent = 'change._case_' + caseName;\n if ( typeof(gina.events[caseEvent]) == 'undefined' ) {\n \n var redefineRulingContext = function($el, rules, c) {\n var _caseName = $el.name;\n if ( allFields[_caseName] != $el.value ) {\n console.debug('case `'+ _caseName +'` is changing from ', allFields[_caseName], ' to ', $el.value );\n \n if ( typeof(fields) == 'undefined') {\n var fields = {};\n }\n var _val = $el.value;\n if ( /^(true|false)$/i.test(_val) ) {\n _val = (/^(true)$/i.test(_val)) ? true : false;\n } \n if ( /^\\d+$/.test(_val) ) {\n _val = parseInt(_val);\n }\n // Saving case current value\n allFields[_caseName] = fields[_caseName] = _val;\n \n // rebind & restart validation in silent mode\n var $_form = $el.form;\n if ($_form) {\n // backup `originalRules` in order to avoid override\n var formInstance = instance['$forms'][$_form.id];\n var customRules = {};\n var caseRules = {};\n var _conditions = [];\n if ( typeof(formInstance.originaRules) == 'undefined' ) {\n formInstance.originaRules = JSON.clone(rules);\n } else {\n //customRules = merge(rules, formInstance.originaRules);\n //customRules = JSON.clone(formInstance.originaRules);\n caseRules = JSON.clone(formInstance.originaRules);\n }\n //var customRules = JSON.clone(formInstance.originaRules);\n \n //var customRules = JSON.clone(rules);\n \n if ( typeof(rules[c]) != 'undefined' && typeof(rules[c].conditions) != 'undefined' ) {\n _conditions = rules[c].conditions;\n } else if (typeof(rules['_case_'+_caseName]) != 'undefined' && typeof(rules['_case_'+_caseName].conditions) != 'undefined') {\n _conditions = rules['_case_'+_caseName].conditions;\n }\n if (_conditions.length > 1) { // more than one condition\n for (let _ci = 0, _ciLen = _conditions.length; _ci < _ciLen; _ci++) {\n if ( \n Array.isArray(_conditions[_ci].case)\n && _conditions[_ci].case.indexOf(fields[_caseName]) > -1\n ||\n _conditions[_ci].case == fields[_caseName]\n ) {\n // Inherited first\n caseRules = merge(_conditions[_ci].rules, caseRules);\n //caseRules = _conditions[_ci].rules;\n }\n } \n } else {\n if ( \n Array.isArray(_conditions[0].case)\n && _conditions[0].case.indexOf(fields[_caseName]) > -1\n ||\n _conditions[0].case == fields[_caseName]\n ) {\n // Inherited first\n caseRules = merge(_conditions[0].rules, caseRules);\n //caseRules = _conditions[0].rules;\n } else {\n var _filter = {};\n _filter['case'] = fields[_caseName];\n try {\n caseRules = merge(new Collection(_conditions).findOne(_filter).rules, caseRules)\n //caseRules = new Collection(_conditions).findOne(_filter).rules\n //caseRules = new Collection(_conditions).findOne(_filter).rules;\n } catch (err) {\n console.warn('Trying to eval undeclared or misconfigured case `\"_case_'+ _caseName +'\"`: `'+ fields[_caseName] +'`.\\Now Skipping it, please check your rules and fix it if needed.');\n // else -> caseRules = {}\n }\n \n _filter = null;\n } \n }\n _conditions = null;\n \n \n \n // Setting up new validation rules\n for (let _f in caseRules) {\n // if ( typeof(customRules[_f]) == 'undefined' ) {\n customRules[_f] = caseRules[_f];\n // } else {\n // // do not override customRules\n // customRules[_f] = merge(customRules[_f], caseRules[_f]);\n // }\n \n }\n // formInstance._current_caseName = _caseName;\n // if ( typeof(formInstance._current_case) == 'undefined' ) {\n // formInstance._current_case = {};\n // }\n // formInstance._current_case[_caseName] = customRules;\n \n caseRules = null;\n // reset binding\n reBindForm($_form, customRules);\n }\n }\n }\n \n \n //console.debug('placing event on ', $fields[caseName].name, caseEvent)\n // We need to bind the case event and the input event at the same time \n // search for grouped els\n // var grpName = $fields[caseName].name;\n // var selectedEls = [], sl = 0;\n // if ( $formOrElement.length > 1 ) {\n // for (let g = 0, gLen = $formOrElement.length; g < gLen; g++) {\n // if ( \n // $formOrElement[g].name == grpName\n // && $formOrElement[g].type == $fields[caseName].type\n // && $formOrElement[g].id != $fields[caseName].id\n // ) {\n // selectedEls[sl] = $formOrElement[g];\n // ++sl;\n // }\n // }\n // } \n // This portion of code is used for case value change\n // var $elementToBind = (selectedEls.length > 0) ? selectedEls : $fields[caseName]; \n // addListener(gina, $elementToBind, 'change.', function(event) {\n // event.preventDefault();\n // console.debug('Now rebinding on ', event.currentTarget.name +' == '+ event.currentTarget.value );\n // redefineRulingContext(event.currentTarget, rules, c);\n // });\n \n // handles _case_* change; also useful if your are using radio tabs as cases triggers\n addListener(gina, $fields[caseName], [ caseEvent, 'change.'+$fields[caseName].id ], function(event) {\n event.preventDefault();\n console.debug('First rebinding on ', event.currentTarget.name +' == '+ event.currentTarget.value );\n redefineRulingContext(event.currentTarget, rules, c);\n });\n \n } // EO caseEvent\n */\n caseValue = allFields[caseName];\n if (isGFFCtx) {\n if (fields[field] == \"true\")\n caseValue = true;\n else if (fields[field] == \"false\")\n caseValue = false;\n }\n \n \n // filtering conditions\n for (var _c = 0, _cLen = rules[c].conditions.length; _c < _cLen; ++_c) {\n \n if (rules[c].conditions[_c].case != caseValue) {\n continue;\n }\n \n // enter condition rules\n for (var _r in rules[c].conditions[_c].rules) {\n if (/^_comment$/i.test(_r)) continue;\n // ignore if we are testing on caseField or if $field does not exist\n if (_r == caseName || !$fields[_r]) continue;\n //if (_r == caseName || !$fields[caseName]) continue;\n // ok, not the current case but still, \n // we want to apply the validation when the field is not yet listed \n if (field != _r && !/^\\//.test(_r) ) {\n if ( \n typeof(fields[_r]) == 'undefined' \n && typeof(allFields[_r]) != 'undefined' \n ) {\n fields[_r] = allFields[_r];\n localRuleObj = ( typeof(rules[_r]) != 'undefined' ) ? rules[_r] : {}; \n rules[_r] = merge(rules[c].conditions[_c].rules[_r], localRuleObj);\n \n checkFieldAgainstRules(_r, rules, fields);\n continue;\n }\n }\n \n \n if ( /^\\//.test(_r) ) { // RegExp found\n re = _r.match(/\\/(.*)\\//).pop(); \n flags = _r.replace('/'+ re +'/', '');\n // fix escaping \"[\" & \"]\"\n re = re.replace(/\\[/g, '\\\\[').replace(/\\]/g, '\\\\]');\n re = new RegExp(re, flags);\n if ( re.test(field) ) { \n // depending on the case value, replace/merge original rule with condition rule\n // if ( typeof(allFields[caseField]) == 'undefined' ) {\n // allFields[caseField] = $fields[c.replace(/^\\_case\\_/, '')].value\n // }\n // caseValue = allFields[caseField];\n // if (isGFFCtx) {\n // if (fields[field] == \"true\")\n // caseValue = true;\n // else if (fields[field] == \"false\")\n // caseValue = false;\n // }\n if ( \n rules[c].conditions[_c].case == caseValue \n ||\n // test for regexp \n /^\\//.test(rules[c].conditions[_c].case) \n && new RegExp(rules[c].conditions[_c].case).test(caseValue) \n ) {\n localRuleObj = ( typeof(rules[_r]) != 'undefined' ) ? rules[_r] : {}; \n rules[_r] = merge(rules[c].conditions[_c].rules[_r], localRuleObj);\n }\n // check each field against rule only if rule exists 1/3\n if ( caseName != _r && typeof(rules[_r]) != 'undefined') {\n checkFieldAgainstRules(_r, rules, fields);\n }\n } \n } else {\n if ( typeof(rules[c].conditions[_c].rules[_r]) != 'undefined' ) {\n // depending on the case value, replace/merge original rule with condition rule\n //caseField = c.replace(/^\\_case\\_/, '');\n caseField = _r;\n caseValue = fields[caseField];\n \n if ( typeof($fields[caseField]) == 'undefined' ) {\n console.warn('ignoring case `'+ caseField +'`: field `'+ +'` not found in your DOM');\n continue;\n }\n // by default\n // if ( typeof(allFields[caseField]) == 'undefined' ) {\n // allFields[caseField] = $fields[caseField].value\n // }\n // caseValue = allFields[caseField];\n // boolean caseValue\n if (\n isGFFCtx \n && /^(true|false)$/i.test(caseValue) \n && typeof(rules[caseField]) != 'undefined'\n && typeof(rules[caseField].isBoolean) != 'undefined' \n && /^(true)$/i.test(rules[caseField].isBoolean)\n ) {\n caseValue = ( /^(true)$/i.test(caseValue) ) ? true : false;\n }\n \n if ( \n //rules[c].conditions[_c].case == caseValue \n typeof(rules[c].conditions[_c].rules[_r]) != 'undefined'\n // ||\n // // test for regexp \n // /^\\//.test(rules[c].conditions[_c].case) \n // && new RegExp(rules[c].conditions[_c].case).test(caseValue)\n ) {\n localRuleObj = ( typeof(rules[c].conditions[_c].rules[_r]) != 'undefined' ) ? rules[c].conditions[_c].rules[_r] : {};\n //rules[_r] = merge(rules[c].conditions[_c].rules[_r], localRuleObj);\n rules[_r] = localRuleObj;\n }\n \n // check each field against rule only if rule exists 2/3\n //if ( caseName != _r && typeof(rules[_r]) != 'undefined' ) {\n if ( caseName != _r && typeof(rules[_r]) != 'undefined' && typeof(fields[_r]) != 'undefined' ) {\n checkFieldAgainstRules(_r, rules, fields);\n }\n } \n }\n }\n }\n } \n }\n \n if (isInCase || caseName == field) continue; \n\n // check each field against rule only if rule exists 3/3\n if ( typeof(rules[field]) != 'undefined' ) {\n //checkFieldAgainstRules(field, rules, fields);\n checkFieldAgainstRules(field, rules, allFields);\n } \n \n if (hasCase) {\n ++i; // add sub level\n conditions = rules['_case_' + field]['conditions'];\n\n if ( !conditions ) {\n throw new Error('[ ginaFormValidator ] case `_case_'+field+'` found without `condition(s)` !\\nPlease, check your delcaration for `_case_'+ field +'`');\n }\n \n \n for (var c = 0, cLen = conditions.length; c<cLen; ++c) {\n // by default\n //caseValue = fields[field];\n caseValue = allFields[field];\n\n if (isGFFCtx) {\n if (fields[field] == \"true\")\n caseValue = true;\n else if (fields[field] == \"false\")\n caseValue = false;\n }\n\n //console.debug(caseValue +' VS '+ conditions[c]['case'], \"->\", (caseValue == conditions[c]['case'] || Array.isArray(conditions[c]['case']) && conditions[c]['case'].indexOf(caseValue) > -1) );\n if ( \n conditions[c]['case'] === caseValue \n ||\n Array.isArray(conditions[c]['case']) && conditions[c]['case'].indexOf(caseValue) > -1 \n ||\n /^\\//.test(conditions[c]['case']) \n ) {\n\n //console.debug('[fields ] ' + JSON.stringify(fields, null, 4));\n localRules = {}; \n // exclude case field if not declared in rules && not disabled\n if ( \n typeof(conditions[c]['rules'][field]) == 'undefined' \n && typeof(allFields[field]) == 'undefined'\n ||\n $fields[field].disabled \n ) {\n conditions[c]['rules'][field] = { exclude: true } \n } \n for (var f in conditions[c]['rules']) {\n if (/^_comment$/i.test(f)) continue;\n //console.debug('F: ', f, '\\nrule: '+ JSON.stringify(conditions[c]['rules'][f], null, 2));\n if ( /^\\//.test(f) ) { // RegExp found\n\n re = f.match(/\\/(.*)\\//).pop(); \n flags = f.replace('/'+ re +'/', '');\n // fix escaping \"[\" & \"]\"\n re = re.replace(/\\[/g, '\\\\[').replace(/\\]/g, '\\\\]');\n re = new RegExp(re, flags);\n\n for (var localField in $fields) {\n if ( re.test(localField) ) {\n if ( /^\\//.test(conditions[c]['case']) ) {\n re = conditions[c]['case'].match(/\\/(.*)\\//).pop();\n flags = conditions[c]['case'].replace('/'+ re +'/', '');\n re = new RegExp(re, flags);\n\n if ( re.test(caseValue) ) {\n localRules[localField] = conditions[c]['rules'][f]; \n }\n\n } else {\n localRules[localField] = conditions[c]['rules'][f]\n }\n \n // we need to add it to fields list if not declared\n if ( \n typeof(fields[localField]) == 'undefined' \n && typeof($fields[localField]) != 'undefined' \n && typeof($fields[localField].value) != 'undefined'\n ) {\n fields[localField] = $fields[localField].value;//caseValue is not goo here\n if (isGFFCtx && /(true|false)/i.test(fields[localField] ) ) {\n if (fields[localField] == \"true\")\n fields[localField] = true;\n else if (fields[localField] == \"false\")\n fields[localField] = false;\n }\n d.addField(localField, fields[localField]);\n if ( typeof(allRules[localField]) != 'undefined' ) {\n localRules[localField] = merge(localRules[localField], allRules[localField])\n }\n }\n }\n }\n\n } else {\n if ( /^\\//.test(conditions[c]['case']) ) {\n \n re = conditions[c]['case'].match(/\\/(.*)\\//).pop(); \n flags = conditions[c]['case'].replace('/'+ re +'/', '');\n // fix escaping \"[\" & \"]\"\n re = re.replace(/\\[/g, '\\\\[').replace(/\\]/g, '\\\\]');\n re = new RegExp(re, flags);\n\n if ( re.test(caseValue) ) {\n localRules[f] = conditions[c]['rules'][f]\n }\n\n } else {\n localRules[f] = conditions[c]['rules'][f]\n }\n \n // we need to add it to fields list if not declared\n // if ( typeof(fields[f]) == 'undefined' ) {\n // fields[f] = caseValue;\n // }\n if ( \n typeof(fields[f]) == 'undefined' \n && typeof($fields[f]) != 'undefined' \n && typeof($fields[f].value) != 'undefined'\n ) {\n fields[f] = $fields[f].value;\n if (isGFFCtx && /(true|false)/i.test(fields[f] ) ) {\n if (fields[f] == \"true\")\n fields[f] = true;\n else if (fields[f] == \"false\")\n fields[f] = false;\n } \n \n d.addField(f, fields[f]);\n if ( typeof(allRules[f]) != 'undefined' ) {\n localRules[f] = merge(localRules[f], allRules[f])\n }\n }\n } \n }\n \n \n \n ++subLevelRules; // add sub level\n if (isGFFCtx)\n forEachField($formOrElement, allFields, allRules, fields, $fields, localRules, cb, i);\n else\n return forEachField($formOrElement, allFields, allRules, fields, $fields, localRules, cb, i);\n }\n \n }\n --i;\n }\n\n \n } // EO for\n } \n \n --subLevelRules;\n\n if (i <= 0 && subLevelRules < 0) {\n \n var errors = d['getErrors']();\n // adding data attribute to handle display refresh\n for (var field in errors) {\n for (rule in errors[field]) {\n if (!fieldErrorsAttributes[field]) {\n fieldErrorsAttributes[field] = ''\n }\n\n if (fieldErrorsAttributes[field].indexOf(rule) < 0)\n fieldErrorsAttributes[field] += rule +' ';\n }\n\n if (isGFFCtx)\n $fields[field].setAttribute('data-gina-form-errors', fieldErrorsAttributes[field].substr(0, fieldErrorsAttributes[field].length-1))\n }\n\n //calling back\n try {\n data = formatData( d['toData']() );\n\n if ( envIsDev && isGFFCtx && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar ) {\n // update toolbar\n if (!gina.forms.validated)\n gina.forms.validated = {};\n \n if (!gina.forms.validated[id])\n gina.forms.validated[id] = {};\n\n var objCallback = {\n id : id,\n validated : data\n };\n\n window.ginaToolbar.update('forms', objCallback);\n }\n } catch (err) {\n throw err\n }\n hasParsedAllRules = true;\n if (!hasBeenValidated && asyncCount <= 0) {\n if ( typeof(cb) != 'undefined' && typeof(cb) === 'function' ) {\n cb._errors = d['getErrors']();\n cb._data = d['toData']();\n triggerEvent(gina, $formOrElement, 'validated.' + id, cb);\n } else {\n hasBeenValidated = true;\n return {\n 'isValid' : d['isValid'],\n 'error' : errors,\n 'data' : data\n }\n }\n }\n }\n }\n \n \n if (isGFFCtx) {\n addListener(gina, $formOrElement, evt, function(event) {\n event.preventDefault();\n \n if (!hasBeenValidated) {\n hasBeenValidated = true;\n hasParsedAllRules = false;\n asyncCount = 0;\n \n var _cb = event.detail;\n var _data = _cb._data || d['toData']();\n var cbErrors = _cb._errors || d['getErrors']() || null;\n \n console.debug('instance errors: ', instance.$forms[id].errors, ' VS cbErrors: ', cbErrors, d['isValid'](), ' VS d.getErrors(): ',d['getErrors']() );\n \n if ( cbErrors.count() > 0 && d['isValid']()) {\n d['isValid'] = function() {\n return false;\n }\n }\n \n _cb({\n 'isValid' : d['isValid'],\n 'error' : cbErrors,\n 'data' : formatData( _data )\n });\n removeListener(gina, event.target, 'validated.' + event.target.id);\n return \n } \n });\n }\n \n // 0 is the starting level\n if (isGFFCtx)\n forEachField($formOrElement, allFields, allRules, fields, $fields, rules, cb, 0);\n else\n return forEachField($formOrElement, allFields, allRules, fields, $fields, rules, cb, 0);\n }\n\n var setupInstanceProto = function() {\n\n instance.target = document;\n instance.setOptions = setOptions;\n instance.getFormById = getFormById;\n instance.validateFormById = validateFormById;\n instance.resetErrorsDisplay = resetErrorsDisplay;\n instance.resetFields = resetFields;\n instance.handleErrorsDisplay = handleErrorsDisplay;\n instance.send = send;\n //instance.handleXhrResponse = handleXhrResponse;\n }\n\n if (isGFFCtx) {\n return init(rules)\n } else {\n return backendInit(rules, data, formId)\n }\n\n};\n\nif ( ( typeof(module) !== 'undefined' ) && module.exports ) {\n // Publish as node.js module\n module.exports = ValidatorPlugin\n} else if ( typeof(define) === 'function' && define.amd) {\n // Publish as AMD module\n define('gina/validator', ['utils/events', 'utils/dom', 'utils/form-validator'], function(){ return ValidatorPlugin })\n};\n",
|
|
45
|
-
"define('gina/toolbar', ['require', 'jquery', 'vendor/uuid'/**, 'utils/merge'*/, 'utils/collection', 'utils/routing', 'gina/storage', 'gina/validator' ], function (require) {\n\n var $ = require('jquery');\n $.noConflict();\n //var merge = require('utils/merge');\n var routing = require('utils/routing');\n var Collection = require('utils/collection');\n var Storage = require('gina/storage');\n //var Validator = require('gina/validator');\n\n /**\n * Toolbar plugin\n * \n * TODO - search using `datatables` plugin (https://stackoverflow.com/questions/10400033/is-there-a-jquery-plugin-like-datatables-for-a-ul)\n */\n function Toolbar() {\n\n //console.debug('Toolbar jquery is ', $.fn.jquery);\n\n var self = {\n version : '1.0.3',\n foldingPaths : {},\n foldingClass : null,\n isUnfolded : null,\n isXHR : false,\n isValidator : false,\n hasParsedUrls : false\n };\n\n var bucket = new Storage({bucket: 'gina'}) // <Bucket>\n , plugins = bucket.Collection('plugin') // <Collection>\n //, validator = new Validator() // <Validator>\n ;\n\n var $toolbar = null\n , settings = null\n , isCollapsed = false\n , $tabs = null\n , $logo = null\n , $panelsContainer = null\n , $panels = null\n , $currentPanel = null\n , panelId = ''\n , $verticalPos = null\n , $horizontalPos = null\n , $toolbarPos = null\n , position = ''\n , $toolbarWidth = null\n , width = 0\n , $toolbarHeight = null\n , toolbarHeight = 0\n , contentHeight = 0\n , keynum = ''\n , lastPressedKey = {}\n , coockie = null\n , $json = null\n , $ginaJson = null\n , $jsonRAW = null\n , originalData = null\n , jsonObject = null\n , lastJsonObjectState = null\n , ginaJsonObject = null\n , forms = null\n , formsIgnored = '.gina-toolbar-options, .gina-toolbar-content'\n , $htmlConfigurationEnvironment = null\n , $htmlData = null\n , $htmlView = null\n , $htmlForms = null\n , $codeFoldingToggle = null\n , codeFolding = true\n , timeoutId = null\n , $copyCache = null\n , copyValue = null\n ;\n\n var init = function () {\n // Get elements\n $toolbar = $('#gina-toolbar');\n if (!$toolbar.length) return false;\n\n $tabs = $toolbar.find('.gina-toolbar-tab > a');\n $logo = $('#gina-toolbar-toggle');\n $panelsContainer = $('#gina-toolbar-panels');\n $panels = $panelsContainer.find('.gina-toolbar-panel');\n $verticalPos = $('#gina-toolbar-vposition');\n $horizontalPos = $('#gina-toolbar-hposition');\n $toolbarPos = $verticalPos.add($horizontalPos);\n $toolbarWidth = $('#gina-toolbar-width');\n $toolbarHeight = $toolbar.find('.gina-toolbar-main');\n $json = $('#gina-toolbar-json');\n $ginaJson = $('#gina-toolbar-gina-json');\n $jsonRAW = $('#gina-toolbar-toggle-code-raw');\n $forms = $('form:not('+ formsIgnored +')');\n $htmlData = $('#gina-toolbar-data-html');\n $htmlView = $('#gina-toolbar-view-html');\n $htmlForms = $('#gina-toolbar-forms-html');\n $htmlConfigurationEnvironment = $('#gina-toolbar-configuration-environment-html')\n $codeFoldingToggle = $('#gina-toolbar-code-toggle');\n\n // Append textarea for copy/paste then select it\n $toolbar.prepend('<textarea class=\"gina-toolbar-copy\"></textarea>');\n $copyCache = $toolbar.find('.gina-toolbar-copy');\n\n // Get toolbar settings\n settings = plugins.findOne({_name: 'toolbar'});\n\n if ( !settings ) {\n // default settings\n settings = {\n _name : 'toolbar',\n _version : self.version,\n _description : 'Toolbar settings',\n _licence : 'MIT',\n _author : [\n {name: 'Fabrice Delaneau', company: 'Freelancer'},\n {name: 'Martin-Luther Etouman', company: 'Rhinostone'}\n ],\n position : 'top-right',\n width : '30',\n panelId : '#gina-toolbar-data',\n isCollapsed : true,\n isUnfolded : [],\n debug : {\n forms : {\n active: false,\n strategy: 'frontend' // by default\n }\n }\n };\n // saving default settings\n plugins.insert(settings);\n settings = plugins.findOne({_name: 'toolbar'});\n\n }\n\n // in case of local storage schema update;\n if (settings._version != self.version) {\n checkSchemaUpdate();\n }\n\n position = settings.position;\n width = settings.width;\n panelId = settings.panelId;\n isCollapsed = settings.isCollapsed;\n\n $toolbar.removeClass('gina-toolbar-hidden');\n handle() // Bind behaviors\n };\n\n\n var checkSchemaUpdate = function () {\n // Run every update from your current version up to the head\n\n if (settings._version < '1.0.1') {\n if (!settings.isUnfolded ) {\n settings.isUnfolded = [];\n }\n if (settings.codeFolding != undefined) {\n delete settings.codeFolding;\n }\n }\n\n if ( typeof(settings.isUnfolded) != 'undefined' && !Array.isArray(settings.isUnfolded) ) {\n settings.isUnfolded = [];\n }\n\n // update version number\n settings._version = self.version;\n\n // save all changes\n settings.save(true);\n }\n\n /**\n * loadData\n *\n * @param {object} [section]\n * @param {object} [data]\n * @param {object} [ginaData]\n *\n * */\n var loadData = function (section, data, ginaData) {\n\n var $currentForms = null;\n try {\n var txt = ($json) ? $json.text() : '';\n if (txt == '' || txt == 'null' ) {\n $json.text('Empty')\n } else {\n jsonObject = JSON.parse( txt );\n ginaJsonObject = JSON.parse($ginaJson.text());\n \n $json.text('');\n\n // backing up document data for restore action\n if (!originalData) {\n \n originalData = {\n jsonObject : JSON.clone(jsonObject),\n ginaJsonObject : JSON.clone( ginaJsonObject)\n };\n lastJsonObjectState = {}; // jsonObject.data\n \n }\n }\n\n } catch (err) {\n \n var sectionStr = ( section ) ? ' [ '+ section + ' ] ' : ' ';\n var _err = 'Could not load'+ sectionStr +'json\\n' + (err.stack||err.message||err);\n if ($json) {\n $json.text(_err);\n } else {\n throw _err;\n }\n \n }\n\n if (jsonObject) {\n\n if (data && !ginaData) {\n if ( !jsonObject[section] )\n jsonObject[section] = {};\n\n jsonObject[section] = ginaJsonObject[section] = data;\n\n } else if ( section == 'data-xhr' && !data && jsonObject['data-xhr'] ) {\n // reset xhr\n delete jsonObject['data-xhr'];\n } else if (ginaData) {\n jsonObject = data;\n ginaJsonObject = ginaData;\n }\n\n\n // Make folding paths\n makeFoldingPaths(jsonObject, '');\n\n // Create DOM from JSON\n // -> Configuration::environment\n // filtering before\n delete jsonObject.environment.routing;\n delete ginaJsonObject.environment.routing;\n delete jsonObject.environment.reverseRouting;\n delete ginaJsonObject.environment.reverseRouting;\n delete jsonObject.environment.forms;\n delete ginaJsonObject.environment.forms;\n $htmlConfigurationEnvironment.html(parseObject(jsonObject.environment, ginaJsonObject.environment));\n\n\n var userObject = { data: jsonObject.data, view: jsonObject.view, forms: jsonObject.forms }\n , ginaObject = { data: ginaJsonObject.data, view: ginaJsonObject.view, forms: ginaJsonObject.forms } ;\n\n\n // xhr mode\n self.initiatedXhrFoldingState = false;\n // validator mode\n self.isValidator = false;\n\n var isXHR = null, isXHRViewData = false;\n\n if ( /^(view-xhr)$/.test(section) ) {\n\n isXHR = true;\n\n userObject.view = jsonObject[section];\n ginaObject.view = ginaJsonObject[section];\n\n userObject.data = jsonObject['data-xhr'];\n ginaObject.data = ginaJsonObject['data-xhr'];\n }\n\n if ( !section || /^(data)$/.test(section) ) {\n \n\n // -> Data\n $htmlData.html('<ul class=\"gina-toolbar-code\">' + parseObject(userObject.data, ginaObject.data, null, isXHR) +'</ul>');\n\n // -> View\n // init view\n var htmlProp = '<div id=\"gina-toolbar-view-html-properties\" class=\"gina-toolbar-section\">\\n' +\n ' <h2 class=\"gina-toolbar-section-title\">properties</h2>\\n' +\n ' <ul class=\"gina-toolbar-properties\"></ul>\\n' +\n '</div>';\n\n $htmlView.html(htmlProp);\n \n $htmlView.html( parseView(userObject.view, ginaObject.view, null, isXHR, $htmlView) );\n\n // -> Forms\n $currentForms = $forms; \n $htmlForms.html('');\n $htmlForms.html( parseForms(userObject.forms, ginaObject.forms, $htmlForms, 0, $currentForms, $currentForms.length, isXHR) );\n // Form binding\n $htmlForms.find('div.gina-toolbar-section > h2').off('click').on('click', function(event) {\n event.preventDefault();\n\n $(this)\n .parent()\n .find('ul').first()\n .slideToggle();\n });\n\n //$htmlForms.html( parseView(jsonObject.forms, ginaJsonObject.forms, null, $htmlForms) );\n } //else \n if ( /^(data-xhr|view-xhr)$/.test(section) ) {\n \n // reset case\n if ( typeof(jsonObject[section]) == 'undefined' || !jsonObject[section] || jsonObject[section] == 'null' ) {\n return false;\n }\n\n // -> XHR Data\n isXHR = true;\n isXHRViewData = (typeof (jsonObject[section].isXHRViewData) != 'undefined') ? true : isXHRViewData;\n \n \n // update data section without erasing old data\n if (!isXHRViewData && !/^(view-xhr)$/.test(section)) {\n \n // also update original data to handle restore action\n if ( typeof (jsonObject['el-xhr']) != 'undefined' ) {\n lastJsonObjectState.data = JSON.clone(jsonObject[section]);\n }\n }\n\n // -> isXHRViewData (from popin) : cleanup\n if (isXHRViewData) {\n delete jsonObject[section].isXHRViewData;\n }\n\n if ( /^(data-xhr)$/.test(section) ) {\n $htmlData.html('<ul class=\"gina-toolbar-code\">' + parseObject(jsonObject[section], ginaJsonObject[section], null, isXHR) +'</ul>');\n } else if ( /^(view-xhr)$/.test(section) ) {\n //$htmlView.html( parseView(userObject.view, ginaObject.view, null, isXHR, $htmlView) );\n // -> View\n // init view\n var htmlProp = '<div id=\"gina-toolbar-view-html-properties\" class=\"gina-toolbar-section\">\\n' +\n ' <h2 class=\"gina-toolbar-section-title\">properties</h2>\\n' +\n ' <ul class=\"gina-toolbar-properties\"></ul>\\n' +\n '</div>';\n\n $htmlView.html(htmlProp);\n $htmlView.html( parseView(jsonObject[section], ginaJsonObject[section], null, isXHR, $htmlView) );\n }\n \n } //else \n if ( /^(el-xhr)$/.test(section) ) {\n // -> XHR Forms\n isXHR = true; \n $currentForms = $('#' + data).find('form:not(' + formsIgnored + ')');\n $htmlForms.html('');\n $htmlForms.html( parseForms(userObject.forms, ginaObject.forms, $htmlForms, 0, $currentForms, $currentForms.length, isXHR ) );\n // Form binding\n $htmlForms.find('div.gina-toolbar-section > h2').off('click').on('click', function(event) {\n event.preventDefault();\n\n $(this)\n .parent()\n .find('ul').first()\n .slideToggle();\n });\n } //else \n if ( /^(forms)$/.test(section) ) {\n isXHR = true;\n self.isValidator = true;\n \n var $form = $('#gina-toolbar-form-' + data.id);\n // for live changes (eg.: on `Validator::getFormById()` call)\n if ( !$form.length ) {\n // crearte toolbar entry for the new form\n $currentForms = $forms; \n $htmlForms.html('');\n $htmlForms.html( parseForms(userObject.forms, ginaObject.forms, $htmlForms, 0, $currentForms, $currentForms.length, isXHR) );\n // Form binding\n $htmlForms.find('div.gina-toolbar-section > h2').off('click').on('click', function(event) {\n event.preventDefault();\n\n $(this)\n .parent()\n .find('ul').first()\n .slideToggle();\n });\n }\n \n // form data sent\n if ( typeof(data.rules) != 'undefined' ) {\n updateForm(data.id, 'rules', data.rules, isXHR)\n }\n \n // form errors\n if ( typeof(data.errors) != 'undefined' && data.errors.count() > 0 ) {\n updateForm(data.id, 'errors', data.errors, isXHR)\n }\n\n // form data sent\n if ( typeof(data.sent) != 'undefined' ) {\n updateForm(data.id, 'sent', data.sent, isXHR)\n }\n }\n\n\n // Manage folding state\n settings.currentFile = jsonObject.file;\n if (!settings.currentFile) {\n // Init currentFile if none exists\n settings.currentFile = jsonObject.file;\n }\n\n if (jsonObject.file == settings.currentFile) {\n // If current page is the same as the previous page, unfold code as neede\n $(document).ready(function () {\n \n if (self.isValidator ) {\n self.isXHR = true;\n if (settings.isUnfolded.length > 0 && !self.initiatedXhrFoldingState) {\n self.initiatedXhrFoldingState = true;\n setTimeout(function () {\n if (settings.isUnfolded.length > 0)\n initFoldingState(settings.isUnfolded, settings.isUnfolded.length, 0);\n }, 200)\n }\n } else {\n if (!isXHR) {\n self.isXHR = false;\n setTimeout(function () {\n if (settings.isUnfolded.length > 0)\n initFoldingState(settings.isUnfolded, settings.isUnfolded.length, 0);\n }, 200)\n } else {\n self.isXHR = true;\n if (settings.isUnfolded.length > 0 && !self.initiatedXhrFoldingState) {\n self.initiatedXhrFoldingState = true;\n initFoldingState(settings.isUnfolded, settings.isUnfolded.length, 0);\n }\n }\n }\n })\n }\n } \n \n if ( !section || section == 'el-xhr' && !self.hasParsedUrls) {\n self.hasParsedUrls = (section && section == 'el-xhr' ) ? true : false;\n parseUrls(section);\n } \n }\n\n\n var initFoldingState = function (unfolded, len, i) {\n\n if (i == len) return false;\n\n var key = unfolded[i];\n var $kel = null;\n\n if ( self.isXHR && /^xhr-/.test(key) ) {\n key = key.replace(/^xhr-/, '');\n $kel = $('.gina-toolbar-xhr-folding-state-'+ key);\n } else {\n $kel = $('.gina-toolbar-folding-state-' + key);\n }\n\n toggleCodeFolding( $kel, function onCodeToggled() {\n i = i + 1;\n initFoldingState(unfolded, len, i)\n });\n }\n\n var handle = function () {\n\n\n // Add folding behavior\n $htmlData\n .add($htmlView).off('click', 'a').on('click', 'a', function(event) {\n event.preventDefault();\n\n toggleCodeFolding( $(this), null, true )\n })\n .add($htmlForms).off('click', 'a').on('click', 'a', function(event) {\n event.preventDefault();\n\n toggleCodeFolding( $(this), null, true )\n });\n\n // Expand/collapse all code\n $codeFoldingToggle.off('click').on('click', function(event) {\n event.preventDefault();\n\n toggleCodeFolding('all', null, true)\n });\n\n // Add value to the clipboard\n $htmlData.add($htmlView, $htmlForms).off('click', '.gina-toolbar-value').on('click', '.gina-toolbar-value', function(event) {\n event.preventDefault();\n try {\n copyValue = $(this).text();\n $copyCache.text(copyValue);\n $copyCache.select();\n document.execCommand('copy', false, null);\n $copyCache.blur();\n } catch(err) {\n alert('Please press Ctrl/Cmd+C to copy the value');\n // throw err;\n }\n\n });\n\n // display RAW\n $jsonRAW.off('click').on('click', function(event){\n if (jsonObject) {\n var jsonOut = window.open(\"\", \"JSON RAW\", \"width=400,height=100\");\n //jsonOut.document.write( '<pre>' + JSON.stringify(jsonObject, null, 2) + '</pre>' );\n jsonOut.document.write( JSON.stringify(jsonObject.data) );\n }\n });\n\n // Tabs\n $tabs.off('click').on('click', function(event) {\n event.preventDefault();\n\n // Hide all panels\n $tabs.removeClass('gina-toolbar-active');\n $panels.removeClass('gina-toolbar-active');\n\n // Show selected tab\n $(this).addClass('gina-toolbar-active');\n\n // Show selected panel\n panelId = $(this).attr('href');\n $currentPanel = $(panelId).addClass('gina-toolbar-active');\n\n // Save current active tab to coockie\n settings.panelId = panelId;\n settings.save()\n });\n\n // Show/hide Toolbar\n $logo.off('click').on('click', function(event) {\n event.preventDefault();\n\n $toolbar.toggleClass('gina-toolbar-collapsed');\n\n // Save current visibility state to coockie\n isCollapsed = $toolbar.hasClass('gina-toolbar-collapsed')\n settings.isCollapsed = isCollapsed;\n settings.save()\n });\n\n // Toolbar position\n $toolbarPos.off('change').on('change', function(event) {\n event.preventDefault();\n\n // Get selected option value\n var vposition = $verticalPos.val();\n var hposition = $horizontalPos.val();\n position = vposition + '-' + hposition\n changeToolbarPosition(position);\n\n // Save new position to coockie\n settings.position = position;\n settings.save()\n });\n\n // Toolbar width\n $toolbarWidth.off('change').on('change', function(event) {\n event.preventDefault();\n\n // Get selected option value\n width = $toolbarWidth.val();\n changeToolbarWidth(width);\n\n // Save new width to coockie\n settings.width = width;\n settings.save()\n });\n\n // Toolbar height\n $(window).off('resize').on('resize', function() {\n changeToolbarHeight();\n });\n\n // Show/hide toolbar using gg shorcut\n $('body').off('keypress').on('keypress', function onKeypressed(event){ \n \n if (!/INPUT|TEXTAREA/.test(event.target.tagName )) {\n if (event.keyCode) {\n // IE\n keynum = event.keyCode;\n } else if (event.which) {\n // Netscape/Firefox/Opera\n keynum = event.which;\n } else {\n // Chrome/Safari\n keynum = event.charCode;\n }\n var now = new Date();\n if (\n typeof lastPressedKey.keynum != \"undefined\"\n && lastPressedKey.keynum == keynum\n && typeof lastPressedKey.pressTime != \"undefined\"\n && now.getTime() - lastPressedKey.pressTime < 500\n ) {\n switch (keynum) {\n case 103: //This is the \"g\" key\n $toolbar.toggle();\n // variousTools.setCookie(\"gina-toolbar[hub]\", params.display.hub, 365);\n break;\n }\n }\n lastPressedKey.pressTime = now.getTime();\n lastPressedKey.keynum = keynum;\n }\n \n });\n\n \n // Updates Toolbar with current values\n\n // Select the current tab\n $tabs.filter('[href=\"' + panelId +'\"]').trigger('click');\n\n // Open toolbar if needed\n if (!isCollapsed) {\n $('#gina-toolbar-toggle').trigger('click');\n }\n\n // Change Toolbar Position and init selects\n changeToolbarPosition(position);\n\n var positions = position.split('-');\n $verticalPos.val(positions[0]);\n $horizontalPos.val(positions[1]);\n\n // Change Toolbar Width and init select\n changeToolbarWidth(width);\n\n $toolbarWidth.val(width);\n\n // Change Toolbar max-Height;\n changeToolbarHeight();\n\n // Parse JSON\n var txt = ($json) ? $json.text() : '';\n // dev only - allows HTML 5 mock\n if ( /^\\{\\{ (.*) \\}\\}/.test(txt) ) {\n // loading mock\n //var url = document.location.protocol + '//' + document.location.pathname.replace('index.html', '');\n //url + 'mock.json';\n loadJSON(txt, loadData); //parse\n\n } else {\n loadData()\n }\n }\n\n\n var changeToolbarPosition = function (position) {\n $toolbar\n .removeClass('gina-toolbar-top-left gina-toolbar-top-right gina-toolbar-bottom-left gina-toolbar-bottom-right')\n .addClass('gina-toolbar-'+ position);\n }\n\n var changeToolbarWidth = function (width) {\n $toolbar\n .removeClass('gina-toolbar-auto gina-toolbar-100 gina-toolbar-80 gina-toolbar-60 gina-toolbar-50 gina-toolbar-40 gina-toolbar-30')\n .addClass('gina-toolbar-'+ width);\n }\n\n var changeToolbarHeight = function () {\n // Use window height - 32px for the header\n toolbarHeight = window.innerHeight - 32;\n $toolbar\n .find('.gina-toolbar-main')\n .css('max-height', toolbarHeight +'px');\n\n checkContentHeight()\n }\n\n var checkContentHeight = function () {\n // check toolbar content against window height\n var $currentMain = $currentPanel.find('.gina-toolbar-main');\n var $currentContent = $currentMain.find('.gina-toolbar-content');\n contentHeight = $currentMain.height();\n if (contentHeight == toolbarHeight) {\n $currentContent.addClass('gina-toolbar-content-end')\n } else {\n $currentContent.removeClass('gina-toolbar-content-end')\n }\n }\n\n var toggleCodeFolding = function ($el, cb, toggledByClick) {\n \n if ( typeof(toggledByClick) == 'undefined' ) {\n var toggledByClick = false\n }\n\n if ($el != undefined && $el.length && $el != 'all') {\n\n // Save element folding state\n self.foldingClass = $el.attr('class');\n var hasXhrFlag = false;\n\n if ( /(gina-toolbar-folding-state-[a-z 0-9_-]+|gina-toolbar-xhr-folding-state-[a-z 0-9_-]+)/i.test(self.foldingClass) ) {\n \n if ( /gina-toolbar-folding-state-[a-z0-9_-]+/i.test(self.foldingClass) ) {\n self.foldingClass = self.foldingClass.match(/gina-toolbar-folding-state-[a-z0-9_-]+/i)[0].replace(/gina-toolbar-folding-state-/, '');\n } else {\n hasXhrFlag = true;\n if ( typeof(self.foldingClass) != 'undefined' )\n self.foldingClass = self.foldingClass.match(/gina-toolbar-xhr-folding-state-[a-z0-9_-]+/i)[0].replace(/gina-toolbar-xhr-folding-state-/, 'xhr-');\n }\n\n if ( settings.isUnfolded.indexOf(self.foldingClass) < 0 ) {\n \n settings.isUnfolded.push(self.foldingClass);\n settings.save();\n \n if (!$el.hasClass('gina-toolbar-unfolded')) {\n $el.addClass('gina-toolbar-unfolded');\n $el.next('ul').slideToggle('fast');\n }\n \n } else {\n\n if ( settings.isUnfolded.indexOf(self.foldingClass) > -1 && $el.hasClass('gina-toolbar-unfolded') ) {\n\n // remove reference & sub-references\n var re = new RegExp('^('+ self.foldingClass +')');\n for (var i = 0, len = settings.isUnfolded.length; i < len; ++i) {\n if ( re.test(settings.isUnfolded[i]) ) {\n if (!self.isValidator && toggledByClick || self.isValidator && hasXhrFlag || toggledByClick ) {\n settings.isUnfolded.splice(i, 1);\n --i\n }\n }\n }\n \n settings.save(true);\n \n if ( settings.isUnfolded.indexOf(self.foldingClass) < 0 ) {\n $el.removeClass('gina-toolbar-unfolded');\n $el.next('ul').slideToggle('fast');\n }\n \n\n } else {\n $el.addClass('gina-toolbar-unfolded');\n $el.next('ul').slideToggle('fast');\n } \n }\n }\n \n }\n\n if (typeof (cb) != 'undefined' && cb != null )\n cb()\n }\n\n var orderKeys = function(obj) {\n\n var newObj = {}\n , k = null\n , keys = []\n , i = 0\n , len = null\n ;\n\n for (k in obj) {\n if ( obj.hasOwnProperty(k) ){\n keys[i] = k;\n ++i\n }\n }\n\n len = keys.length;\n keys.sort();\n\n for (i = 0; i < len; ++i) {\n k = keys[i];\n newObj[k] = obj[k];\n }\n\n return newObj\n }\n\n var normalizeFoldingStateName = function(stateSection, stateName) {\n \n var foldingStateName = '', section = null, name = null;\n\n if ( typeof(stateSection) != 'undefined' && stateSection != '' ) {\n \n section = stateSection;\n if ( typeof(stateSection) == 'string' ) {\n section = stateSection\n .replace(/(\\]\\[|\\[)/g, '-')\n .replace(/\\]/, '')\n .replace(/[^A-Za-z0-9_-]/g, '_')\n }\n \n foldingStateName += section + '-'\n }\n\n if ( typeof(stateName) != 'undefined' && stateName != '' ) {\n\n name = stateName;\n if ( typeof(stateName) == 'string' ) {\n name = stateName\n .replace(/(\\]\\[|\\[)/g, '-')\n .replace(/\\]/, '')\n }\n \n foldingStateName += name\n } else {\n foldingStateName = foldingStateName.substr(0, foldingStateName.length-1)\n }\n \n return foldingStateName.trim()\n }\n\n var parseObject = function(obj, ginaObj, elId, elIsXHR, elSection) {\n\n var html = '';\n var id = ( typeof(elId) != 'undefined' && elId != null ) ? elId.replace(/[^A-Za-z0-9_-]/g, '_') : '';\n var section = ( typeof(elSection) != 'undefined' && elSection != null ) ? elSection : '';\n var isXHR = ( typeof(elIsXHR) != 'undefined' && elIsXHR != null ) ? '-xhr' : '';\n var count = '';\n var objType = '';\n var isEmptyClass = null;\n\n obj = orderKeys(obj);\n ginaObj = orderKeys(ginaObj);\n\n for (var i in obj) {\n //console.log('i', i);\n //if ( /^(_uuid)$/.test(i) ) continue;\n\n if ( typeof(obj[i]) == 'object' && !Array.isArray(obj[i]) && obj[i] !== null ) { // parse\n //id += i + '-';\n id += '-' + i.replace(/[^A-Za-z0-9_-]/g, '_');\n isEmptyClass = (obj[i].count() > 0 || typeof(ginaObj[i]) != 'undefined' && ginaObj[i].count() > 0) ? '' : ' is-empty';\n\n html += '<li class=\"gina-toolbar-object\">';\n html += '<a href=\"#\" class=\"gina-toolbar-key gina-toolbar'+ isXHR +'-folding-state-'+ normalizeFoldingStateName( section, i.replace(/[^A-Za-z0-9_-]/g, '_') ) + isEmptyClass +'\">'+ i +' <span>{ }</span></a>';\n html += '<ul class=\"gina-toolbar-object\">' + parseObject(obj[i], ginaObj[i], id, elIsXHR, elSection) +'</ul>';\n html += '</li>';\n // clear one level\n //id = id.substr(0, id.length - i.length - 1);\n id = id.substr(0, id.length - i.length);\n } else if ( Array.isArray(obj[i]) ) {\n //id += i + '-';\n id += '-' + i.replace(/[^A-Za-z0-9_-]/g, '_');\n isEmptyClass = (obj[i].length > 0 || typeof(ginaObj[i]) != 'undefined' && ginaObj[i].length > 0) ? '' : ' is-empty';\n\n html += '<li class=\"gina-toolbar-collection\">';\n html += '<a href=\"#\" class=\"gina-toolbar-key gina-toolbar'+ isXHR +'-folding-state-'+ normalizeFoldingStateName( section, i.replace(/[^A-Za-z0-9_-]/g, '_') ) + isEmptyClass +'\">'+ i +' <span>['+ obj[i].length +']</span></a>';\n html += '<ul class=\"gina-toolbar-collection\">' + parseCollection(obj[i], ginaObj[i], id, elIsXHR, elSection) +'</ul>';\n html += '</li>';\n // clear one level\n //id = id.substr(0, id.length - i.length - 1);\n id = id.substr(0, id.length - i.length);\n } else {\n objType = (ginaObj[i] === null) ? 'null' : typeof(ginaObj[i]);\n if ( objType == 'undefined' ) { // new key declaration added by user\n html += '<li class=\"gina-toolbar-key-value\">';\n html += '<span class=\"gina-toolbar-key gina-toolbar-key-added\">'+ i +':</span> <span class=\"gina-toolbar-value gina-toolbar-value-type-is-'+ objType +'\">'+ obj[i] +'</span>';\n html += '</li>';\n } else {\n\n //if (/^_comment/.test(i) ) continue;\n\n if (obj[i] !== ginaObj[i] ) {\n html += '<li class=\"gina-toolbar-key-value gina-toolbar-is-overridden\">';\n html += '<span class=\"gina-toolbar-key\">'+ i +':</span> <span class=\"gina-toolbar-value\">'+ ginaObj[i] +'</span>';\n html += '</li>';\n\n html += '<li class=\"gina-toolbar-key-value\">';\n html += '<span class=\"gina-toolbar-key\">'+ i +':</span> <span class=\"gina-toolbar-value gina-toolbar-value-type-is-'+ objType +'\">'+ obj[i] +'</span>';\n html += '</li>';\n } else {\n html += '<li class=\"gina-toolbar-key-value\">';\n html += '<span class=\"gina-toolbar-key\">'+ i +':</span> <span class=\"gina-toolbar-value gina-toolbar-value-type-is-'+ objType +'\">'+ obj[i] +'</span>';\n html += '</li>';\n }\n }\n }\n }\n return html\n }\n\n var parseCollection = function (arr, ginaArr, elId, elIsXHR, elSection) {\n var html = '';\n var id = ( typeof(elId) != 'undefined' && elId != null ) ? elId : '';\n var section = ( typeof(elSection) != 'undefined' && elSection != null ) ? elSection : '';\n var isXHR = ( typeof(elIsXHR) != 'undefined' && elIsXHR != null ) ? '-xhr' : '';\n\n // patch \n if (!ginaArr) {\n ginaArr = [];\n }\n for (var i = 0, len = arr.length; i<len; ++i) {\n if ( typeof(arr[i]) == 'object' && !Array.isArray(arr[i]) ) {\n //id += i + '-';\n // patch \n if (!ginaArr[i]) {\n ginaArr[i] = arr[i]\n }\n\n id += '-'+ i;\n if (section == '') {\n section = id;\n }\n html += '<li class=\"gina-toolbar-object\">';\n html += '<a href=\"#\" class=\"gina-toolbar-key gina-toolbar'+ isXHR +'-folding-state-'+ normalizeFoldingStateName( section, i ) +'\">'+ i +' <span>{ }</span></a>';\n html += '<ul class=\"gina-toolbar-object\">' + parseObject(arr[i], ginaArr[i], id, elIsXHR, elSection) +'</ul>';\n html += '</li>';\n // clear one level\n id = id.substr(0, id.length - i.toString().length - 1);\n\n } else if ( Array.isArray(arr[i]) ) {\n //id += i + '-';\n id += '-'+ i;\n if (section == '') {\n section = id;\n }\n html += '<li class=\"gina-toolbar-collection\">';\n html += '<a href=\"#\" class=\"gina-toolbar-key gina-toolbar'+ isXHR +'-folding-state-'+ normalizeFoldingStateName( section, i ) +'\">'+ i +'<span>[ ]</span></a>';\n html += '<ul class=\"gina-toolbar-collection\">' + parseCollection(arr[i], ginaArr[i], id, elIsXHR, elSection) +'</ul>';\n html += '</li>';\n // clear one level\n //id = id.substr(0, id.length - i.toString().length - 1);\n id = id.substr(0, id.length - i.toString().length);\n } else {\n html += '<li class=\"gina-toolbar-key-value\"><span class=\"gina-toolbar-key\">'+ i +':</span> <span class=\"gina-toolbar-value\">'+ arr[i] +'</span></li>';\n }\n }\n return html\n }\n\n var parseView = function (obj, ginaObj, elId, elIsXHR, $html, $root) {\n \n var id = (elId != null) ? elId.replace(/[^A-Za-z0-9_-]/g, '_') : '';\n var section = null;\n var isXHR = ( typeof(elIsXHR) != 'undefined' && elIsXHR != null ) ? '-xhr' : '';\n var count = '';\n var objType = '';\n var hasParent = false;\n var $parent = null;\n var parentId = null;\n\n obj = orderKeys(obj);\n ginaObj = orderKeys(ginaObj);\n\n if (!$root)\n $root = $html;\n\n for (var i in obj) { \n section = i;\n if ( typeof(obj[i]) == 'object' && !Array.isArray(obj[i]) && obj[i] !== null ) { // parse\n\n $parent = $('#gina-toolbar-view-' + id.substr(0, id.length - 1));\n hasParent = ( $parent.length ) ? true : false;\n\n if (!hasParent ) {\n id += i.replace(/[^A-Za-z0-9_-]/g, '_') + '-';\n\n if (i == 'params') { // force to top \n var htmlParams = '<div id=\"gina-toolbar-view-'+ id.substr(0, id.length - 1) +'\" class=\"gina-toolbar-section\">' +\n '<h2 class=\"gina-toolbar-section-title\">'+ id.substr(0, id.length - 1) +'</h2>' +\n '<ul class=\"'+ id.substr(0, id.length - 1) +'\"></ul>' +\n '</div>';\n\n $('#gina-toolbar-view-html-properties')\n .before(htmlParams);\n } else {\n \n if ( !/^html/.test(id) ) {\n \n var htmlOther = '<div id=\"gina-toolbar-view-'+ id.substr(0, id.length - 1) +'\" class=\"gina-toolbar-section\">' +\n '<h2 class=\"gina-toolbar-section-title\">'+ id.substr(0, id.length - 1) +'</h2>' +\n '<ul class=\"'+ id.substr(0, id.length - 1) +'\"></ul>' +\n '</div>';\n\n $html\n .append(htmlOther);\n }/** else { // add to properties section\n $root\n .find('.gina-toolbar-properties')\n .append('ul.' + id.substr(0, id.length - 1))\n }*/\n \n }\n\n parseView(obj[i], ginaObj[i], id, elIsXHR, $html.find('ul.'+ id.substr(0, id.length - 1)), $root );\n\n } else {\n\n parentId = id + i.replace(/[^A-Za-z0-9_-]/g, '_') + '-';\n\n $parent\n .find('ul.'+ id.substr(0, id.length - 1))\n .append('<li class=\"gina-toolbar-object\"><a href=\"#\" class=\"gina-toolbar-key gina-toolbar'+ isXHR +'-folding-state-'+ normalizeFoldingStateName( i.replace(/[^A-Za-z0-9_-]/g, '_'), parentId.substr(0, parentId.length - 1) ) +'\">'+ i +' <span>{ }</span></a><ul class=\"gina-toolbar-object '+ parentId.substr(0, parentId.length - 1) +'\"></ul></li>');\n\n parseView(obj[i], ginaObj[i], parentId, elIsXHR, $parent.find('ul.'+ id.substr(0, id.length - 1)), $root );\n\n id += i.replace(/[^A-Za-z0-9_-]/g, '_') + '-';\n }\n\n\n // clear one level\n id = id.substr(0, id.length - i.length - 1);\n\n\n } else if ( Array.isArray(obj[i]) ) { // parse collection\n\n \n \n $parent = $('#gina-toolbar-view-' + id.substr(0, id.length - 1));\n \n hasParent = ( $parent.length ) ? true : false;\n \n if ( !hasParent || /^html/.test(id) ) { \n \n $parent = $('.' + id);\n parentId = id + i.replace(/[^A-Za-z0-9_-]/g, '_') + '-';\n\n $parent\n //.find('ul.'+ id.substr(0, id.length - 1))\n .append('<li class=\"gina-toolbar-collection\"><a href=\"#\" class=\"gina-toolbar-key gina-toolbar'+ isXHR +'-folding-state-'+ normalizeFoldingStateName( i.replace(/[^A-Za-z0-9_-]/g, '_'), parentId.substr(0, parentId.length - 1) ) +'\">'+ i +' <span>['+ obj[i].length +']</span></a><ul> '+ parseCollection(obj[i], ginaObj[i], parentId, $parent.find('li ul.'+ id.substr(0, id.length - 1)), section )+'</ul></li>');\n\n \n //parentId = parentId.substr(0, parentId.length - 1)+ '-';\n //parentId = id.substr(0, id.length - i.length - 1); \n //parseView(obj[i], ginaObj[i], parentId, elIsXHR, $parent.find('ul.'+ parentId.substr(0, parentId.length - 1)), $root );\n\n //id += i.replace(/[^A-Za-z0-9_-]/g, '_') + '-';\n //$parent = $('#gina-toolbar-view-' + id.substr(0, id.length - 1));\n id += i.replace(/[^A-Za-z0-9_-]/g, '_') + '-';\n } else { \n \n \n parentId = id + i.replace(/[^A-Za-z0-9_-]/g, '_') + '-';\n\n $parent\n .find('li.'+ id.substr(0, id.length - 1) +' ul')\n .append('<li class=\"gina-toolbar-collection\"><a class=\"gina-toolbar-key gina-toolbar'+ isXHR +'-folding-state-'+ normalizeFoldingStateName( i.replace(/[^A-Za-z0-9_-]/g, '_'), parentId.substr(0, parentId.length - 1) ) +'\">'+ i +' <span>['+ obj[i].length +']</span></a><ul>'+ parseCollection(obj[i], ginaObj[i], parentId, $parent.find('li ul.'+ id.substr(0, id.length - 1)), section ) +'</ul></li>');\n\n id += i.replace(/[^A-Za-z0-9_-]/g, '_') + '-';\n \n }\n \n\n // if ( !hasParent || /^html/.test(id) ) { \n // id = id + i.replace(/[^A-Za-z0-9_-]/g, '_') + '-';\n // $root\n // .find('.gina-toolbar-properties')\n // .append('<li class=\"gina-toolbar-collection\"><a class=\"gina-toolbar-key gina-toolbar'+ isXHR +'-folding-state-'+ normalizeFoldingStateName( i.replace(/[^A-Za-z0-9_-]/g, '_'), id.substr(0, id.length - 1) ) +'\">'+ i +' <span>['+ obj[i].length +']</span></a><ul>'+ parseCollection(obj[i], ginaObj[i], parentId, $root.find('.gina-toolbar-properties'), section) +'</ul></li>');\n\n\n // } else { \n \n \n // parentId = id + i.replace(/[^A-Za-z0-9_-]/g, '_') + '-';\n\n // $parent\n // .find('li.'+ id.substr(0, id.length - 1) +' ul')\n // .append('<li class=\"gina-toolbar-collection\"><a class=\"gina-toolbar-key gina-toolbar'+ isXHR +'-folding-state-'+ normalizeFoldingStateName( i.replace(/[^A-Za-z0-9_-]/g, '_'), parentId.substr(0, parentId.length - 1) ) +'\">'+ i +' <span>['+ obj[i].length +']</span></a><ul>'+ parseCollection(obj[i], ginaObj[i], parentId, $parent.find('li ul.'+ id.substr(0, id.length - 1)), section ) +'</ul></li>');\n\n // id += i.replace(/[^A-Za-z0-9_-]/g, '_') + '-';\n // }\n\n // clear one level\n id = id.substr(0, id.length - i.length - 1);\n } else {\n \n \n \n objType = (ginaObj[i] === null) ? 'null' : typeof(ginaObj[i]);\n if ( objType == 'undefined' ) { // new key declaration added by user\n if (/\\-$/.test(id)) {\n id = id.substr(0, id.length - 1);\n }\n \n if (!id) continue;\n \n $html\n .find('ul.' + id)\n .append('<li class=\"gina-toolbar-key-value\"><span class=\"gina-toolbar-key gina-toolbar-key-added\">'+ i +':</span> <span class=\"gina-toolbar-value gina-toolbar-value-type-is-'+ objType +'\">'+ obj[i]+'</span></li>');\n\n } else {\n\n //if (/^_comment/.test(i) ) continue;\n\n if (obj[i] !== ginaObj[i] ) {\n if (!id) {\n id += i.replace(/[^A-Za-z0-9_-]/g, '_') + '-';\n }\n \n try {\n $html\n .find('ul.' + id)\n .append('<li class=\"gina-toolbar-key-value gina-toolbar-is-overridden\"><span class=\"gina-toolbar-key\">'+ i +':</span> <span class=\"gina-toolbar-value\">'+ ginaObj[i] +'</span></li>');\n\n $html\n .find('ul.' + id)\n .append('<li class=\"gina-toolbar-key-value\"><span class=\"gina-toolbar-key\">'+ i +':</span> <span class=\"gina-toolbar-value gina-toolbar-value-type-is-'+ objType +'\">'+ obj[i] +'</span></li>')\n\n } catch (err) {\n throw new Error('GinaToolbarError: `ul.'+ id +'` not found');\n }\n \n } else {\n\n if ( !id || /^html\\-properties/.test(id) ) { // properties case\n // if (id) {\n // $html\n // .find('ul.' + id)\n // .append('<li class=\"gina-toolbar-key-value\"><span class=\"gina-toolbar-key\">'+ i +':</span> <span class=\"gina-toolbar-value gina-toolbar-value-type-is-'+ objType +'\">'+ obj[i] +'</span></li>')\n // } else {\n $root\n .find('.gina-toolbar-properties')\n .append('<li class=\"gina-toolbar-key-value\"><span class=\"gina-toolbar-key\">'+ i +':</span> <span class=\"gina-toolbar-value gina-toolbar-value-type-is-'+ objType +'\">'+ obj[i] +'</span></li>')\n //} \n \n } else {\n \n $root\n .find('ul.' + id.substr(0, id.length - 1))\n .append('<li class=\"gina-toolbar-key-value\"><span class=\"gina-toolbar-key\">'+ i +':</span> <span class=\"gina-toolbar-value gina-toolbar-value-type-is-'+ objType +'\">'+ obj[i] +'</span></li>')\n }\n }\n }\n }\n }\n\n return $root.html()\n }\n\n var parseSection = function (rules, id, elIsXHR, section) {\n\n return parseObject(rules, rules, id, elIsXHR, section)\n }\n \n var parseUrls = function(section) {\n \n var $el = null;\n var $currentPopin = (gina.hasPopinHandler) ? gina.popin.getActivePopin() : null;\n var isPopinContext = ( gina.hasPopinHandler ) ? true : false;\n if ( isPopinContext ) {\n $el = $('#' + $currentPopin.id );\n } else {\n $el = $('body');\n }\n \n // look for `404: `\n var found = {}\n , foundStr = null\n , formMethod = null\n , f = 0\n , fLen = 0\n ;\n var matched = $el.html().match(/404\\:\\[(.+)\\](.+)@(.+)\\\"/gm);\n if (matched) {\n f = 0; fLen = matched.length;\n for (; f < fLen; ++f) {\n foundStr = matched[f].replace(/\\\"(.*)|\\\"/g, '');\n formMethod = foundStr.match(/\\[(.*)\\]/g, '')[0].replace(/\\[|\\]/g,'');\n \n routing.getRouteByUrl(foundStr, formMethod)\n }\n } \n \n printLogs();\n \n //console.debug('popinIsActive: '+ isPopinContext +'isXHR: ', self.isXHR, ' -> ' + section, routing.notFound);\n }\n \n var printLogs = function() {\n fLen = routing.notFound.count();\n if ( fLen > 0 ) { \n for (f in routing.notFound) {\n console.warn( '(x'+ routing.notFound[f].count +') ' + f + ' => ' + routing.notFound[f].message );\n }\n }\n }\n\n var parseForms = function (obj, ginaObj, $html, i, $forms, len, elIsXHR) {\n \n if (!len) return false;\n\n var attributes = $forms[i].attributes;\n var formMethod = null;\n var attrClass = 'gina-toolbar-form-attributes';\n var id = $forms[i].getAttribute('id') || $forms[i].id; \n var section = attrClass; // by default\n var isXHR = ( typeof(elIsXHR) != 'undefined' && elIsXHR != null ) ? '-xhr' : '';\n // form fields set\n // var fields = validator\n // .getFormById(id)\n // .fieldsSet;\n\n var $form = $(\n '<div id=\"gina-toolbar-form-'+ id +'\" class=\"gina-toolbar-section\">' +\n '<h2 class=\"gina-toolbar-section-title\">'+ id +'</h2>' +\n '<ul class=\"gina-toolbar-section-content gina-toolbar-code\" style=\"display: none;\">' +\n '<li class=\"'+ attrClass +'\">' +\n '<h3 class=\"gina-toolbar-sub-section-title\">'+ attrClass.replace(/gina-toolbar-form-/, '') +'</h3>' +\n '<ul class=\"gina-toolbar-code\"></ul>' +\n '</li>' +\n '</ul>' +\n '</div>');\n\n var key = null\n , val = null\n , content = null\n , hasEvents = false\n , routeObj = null\n ;\n\n // testing for action attr to add action route \n \n\n // adding form attributes\n for ( var a = 0, aLen = attributes.length; a < aLen; ++a ) {\n\n key = attributes[a].name;\n val = attributes[a].nodeValue;\n\n // filters\n if ( /^method$/.test(key) )\n val = val.toUpperCase();\n\n if ( /^class$/.test(key) && /\\s+/.test(val) )\n val = '<ul><li>'+ val.replace(/\\s+/g, '</li><li>') +'</li></ul>';\n\n if ( /^action$/.test(key) ) {\n \n formMethod = ( typeof(attributes['method']) != 'undefined' ) ? attributes['method'].nodeValue : undefined; \n \n if (!formMethod) {\n console.warn('[ ToolbarFormHelper::UndefinedMethod : form `'+ attributes['id'].nodeValue +'` method attribute cannot be left undefined !'); \n }\n \n routeObj = routing.getRouteByUrl(val, formMethod); \n\n if ( typeof(routeObj) == 'undefined' || !routeObj ) {\n routeObj = {\n name: 'not found',\n namespace: 'not found',\n param: {\n control: 'not found',\n file: 'not found'\n }\n }\n } \n \n val = '<ul>' +\n '<li>' +\n '<span class=\"gina-toolbar-key\">url</span>' +\n '<span class=\"gina-toolbar-value\">' + (val || '#') + '</span>' +\n '</li>' +\n '<li>' +\n '<span class=\"gina-toolbar-key\">route</span>' +\n '<span class=\"gina-toolbar-value\">' + routeObj.name +'</span>' +\n '</li>' +\n '<li>' +\n '<span class=\"gina-toolbar-key\">namespace</span>' +\n '<span class=\"gina-toolbar-value\">' + (routeObj.namespace || 'root controller') + '</span>' +\n '</li>' +\n '<li>' +\n '<span class=\"gina-toolbar-key\">control</span>' +\n '<span class=\"gina-toolbar-value\">' + routeObj.param.control + '</span>' +\n '</li>' +\n '<li>' +\n '<span class=\"gina-toolbar-key\">file</span>' +\n '<span class=\"gina-toolbar-value\">' + routeObj.param.file + '</span>' +\n '</li>' +\n '<ul>';\n\n content = '<li>' +\n '<span class=\"gina-toolbar-key\">' + key + ':</span>' +\n '<span class=\"gina-toolbar-value\">' + val + '</span>' +\n '</li>';\n }\n\n //content = val;\n\n\n // events\n if ( /^data-gina-form-event/.test(key) ) {\n section = 'events';\n hasEvents = ( $form\n .find('.'+ attrClass)\n .find('.gina-toolbar-key-events').length ) ? true : false;\n\n key = key.replace(/^data-gina-form-event-/, '');\n\n if (!hasEvents) {\n // adding event sub section\n $form\n .find('ul.gina-toolbar-section-content')\n .append('<li class=\"gina-toolbar-form-'+ section +'\">' +\n '<h3 class=\"gina-toolbar-sub-section-title\">'+ section +'</h3>' +\n '<ul class=\"gina-toolbar-code\"></ul>' +\n '</li>');\n\n }\n\n \n content = '<li>' +\n '<span class=\"gina-toolbar-key\">'+ key +':</span>' +\n '<span class=\"gina-toolbar-value\">'+ val +'</span>' +\n '</li>';\n\n\n $form\n .find('ul.gina-toolbar-section-content')\n .find('li.gina-toolbar-form-'+ section +' > ul')\n .append(content)\n\n\n } else { // normal case\n\n if (!/^action$/.test(key)) {\n content = '<li>' +\n '<span class=\"gina-toolbar-key\">' + key + ':</span>' +\n '<span class=\"gina-toolbar-value\">' + val + '</span>' +\n '</li>';\n }\n\n $form\n .find('ul.gina-toolbar-section-content')\n .find('li.'+ attrClass +' > ul')\n .append(content)\n }\n\n\n }\n\n // adding form rules\n var rules = null;\n\n try {\n \n var dataRule = $forms[i].getAttribute('data-gina-form-rule');\n \n if ( typeof(dataRule) != 'undefined' && dataRule!= null ) {\n rules = eval('gina.forms.rules.' + dataRule.replace(/-/g, '.'))\n } else {\n rules = eval('gina.forms.rules.' + id.replace(/-/g, '.'))\n }\n \n } catch (err) {}\n\n if ( rules ) {\n section = 'rules';\n $form\n .find('ul.gina-toolbar-section-content')\n .append('<li class=\"gina-toolbar-form-'+ section +'\">' +\n '<h3 class=\"gina-toolbar-sub-section-title\">'+ section +'</h3>' +\n '<ul class=\"gina-toolbar-properties\">'+ parseSection( rules, id, elIsXHR, section ) +'</ul>' +\n '</li>'); \n \n }\n\n\n\n $html.append($form);\n\n ++i;\n\n if (i < len) {\n parseForms(obj, ginaObj, $html, i, $forms, len, elIsXHR)\n }\n }\n\n var updateForm = function(id, section, obj, elIsXHR) {\n\n var $form = $('#gina-toolbar-form-' + id);\n\n // reset\n $section = $form\n .find('ul.gina-toolbar-section-content')\n .find('li.gina-toolbar-form-'+ section + '> ul');\n\n if ($section.length > 0) { // update\n\n if ( obj.count() == 0 ) { // no errors remove section\n $form\n .find('ul.gina-toolbar-section-content')\n .find('li.gina-toolbar-form-' + section)\n .remove();\n return false\n }\n\n $section\n .html( parseSection( obj, id, elIsXHR, section ) );\n\n } else { // init\n\n $form\n .find('ul.gina-toolbar-section-content')\n .append('<li class=\"gina-toolbar-form-'+ section +'\">' +\n '<h3 class=\"gina-toolbar-sub-section-title\">'+ section +'</h3>' +\n '<ul class=\"gina-toolbar-properties\">'+ parseSection( obj, id, elIsXHR, section ) +'</ul>' +\n '</li>');\n }\n\n // Form binding\n var $sectionContent = $form.find('ul.gina-toolbar-section-content');\n if ( !$sectionContent.is(':visible') ) {\n $sectionContent.slideToggle()\n }\n \n }\n\n var createInputFile = function(id, label) {\n\n var html = null;\n\n html = '<label class=\"gina-toolbar-input-file\">';\n html += '<input type=\"file\" multiple id=\"' + id +'\">';\n html += label;\n html += '</label>';\n\n return html\n }\n\n var loadJSON = function(txt, cb) {\n\n var html = createInputFile('mock', 'Select your JSON file');\n\n $htmlData.html(html);\n $json.text('');\n\n $htmlData.find('input').off('change').on('change', function(e) {\n\n var files = $(this)[0].files;\n var file = null;\n var reader = null;\n\n\n if (files.length == 1) {\n file = $(this)[0].files[0]; // jQuery way\n reader = new FileReader();\n reader.addEventListener('load', function(){\n // user\n $json.text(reader.result);\n // gina <- being duplicated to prevent bugs\n $ginaJson.text(reader.result);\n cb();\n }, false);\n\n reader.readAsBinaryString(file)\n } else {\n var done = 0;\n var complete = function (done) {\n\n if (done == files.length) {\n cb()\n }\n };\n\n reader = [];\n\n for (var i = 0, len = files.length; i < len; ++i) {\n file = files[i];\n switch (true) {\n case /user/.test(file.name):\n\n reader[i] = new FileReader();\n reader[i].addEventListener('load', function onEventListenerAdded(e){\n\n // user\n $json.text(e.currentTarget.result);\n ++done;\n complete(done)\n }, false);\n\n reader[i].readAsBinaryString(file);\n\n break;\n\n case /gina/.test(file.name):\n //console.log(file);\n reader[i] = new FileReader();\n reader[i].addEventListener('load', function onEventListenerAdded(e){\n // gina\n $ginaJson.text(e.currentTarget.result);\n ++done;\n complete(done)\n }, false);\n\n reader[i].readAsBinaryString(file);\n\n break;\n }\n }\n }\n\n });\n\n return false;\n }\n\n var makeFoldingPaths = function(obj, tmp) {\n for (var r in obj) {\n if ( typeof(obj[r]) == 'object' ) {\n self.foldingPaths[tmp + r] = tmp + r;\n makeFoldingPaths(obj[r], tmp + r+'-');\n }\n }\n }\n\n this.update = function (section, data) {\n loadData(section, data);\n }\n\n this.restore = function () {\n // get last jsonObject.data state\n if (lastJsonObjectState && typeof (lastJsonObjectState.data) != 'undefined' ) {\n originalData.jsonObject.data = lastJsonObjectState.data;\n }\n \n loadData('data', originalData.jsonObject, originalData.ginaJsonObject);\n self.hasParsedUrls = false;\n routing.notFound = {};\n }\n\n \n if ( typeof(gina.validator) != 'undefined' ) {\n gina.validator.on('initialized', function onValidatorReady(){\n console.log('toolbar validator ready');\n init();\n })\n } else {\n init();\n } \n \n }\n\n return Toolbar\n});\n",
|
|
46
|
-
"define('gina', [ 'require', 'vendor/uuid', 'utils/merge', 'utils/events', 'helpers/prototypes', 'helpers/dateFormat', 'gina/toolbar' ], function (require) {\n \n \n var eventsHandler = require('utils/events'); // events handler\n var merge = require('utils/merge');\n var dateFormat = require('helpers/dateFormat')(); \n var prototypes = require('helpers/prototypes')({ dateFormat: dateFormat });\n var uuid = require('vendor/uuid');\n\n\n\n /**\n * Imports & definitions\n * */\n\n var jQuery = (window['jQuery']) ? window['jQuery'] : null;\n\n if (!window.process ) {\n (function(window, nextTick, process, prefixes, i, p, fnc) {\n p = window[process] || (window[process] = {});\n while (!fnc && i < prefixes.length) {\n fnc = window[prefixes[i++] + 'requestAnimationFrame'];\n }\n p[nextTick] = p[nextTick] || (fnc && fnc.bind(window)) || window.setImmediate || window.setTimeout;\n })(window, 'nextTick', 'process', 'r webkitR mozR msR oR'.split(' '), 0);\n }\n\n if (!window.getComputedStyle) {\n /**\n * Returns the roster widget element.\n * @this {Window}\n * @returns {ComputedStyle}\n */\n\n window.getComputedStyle = function(el, pseudo) {\n this.el = el;\n this.getPropertyValue = function(prop) {\n var re = /(\\-([a-z]){1})/g;\n if (prop == 'float') {\n prop = 'styleFloat'\n }\n if (re.test(prop)) {\n prop = prop.replace(re, function () {\n return arguments[2].toUpperCase()\n })\n }\n return el.currentStyle[prop] ? el.currentStyle[prop] : null\n }\n return this\n }\n }\n\n function construct(gina) {\n\n this.plugin = 'gina';\n\n var events = [ 'ginaloaded', 'ready' ];\n\n /**\n * setOptions\n * Override default config options or add new options properties\n *\n * @param {object} options\n * */\n var setOptions = function(options) {\n proto.config = merge(proto.config, options, true)\n }\n\n var proto = { // instance proto\n 'id' : 'gina-' + uuid.v1(),\n\n 'plugin' : this.plugin,\n 'on' : on,\n 'eventData' : {},\n 'target' : document, // by default\n };\n\n document.id = proto.id;\n\n var $instance = {\n 'id' : proto.id,\n\n 'isFrameworkLoaded' : false,\n 'hasValidator' : false,\n 'hasPopinHandler' : false,\n 'config' : {},\n 'registeredEvents' : {},\n 'events' : {},\n\n 'setOptions' : setOptions\n };\n \n // iframe case\n if ( typeof(parent.window['gina']) != 'undefined' ) {\n // inheriting from parent frame instance\n window['gina'] = merge((window['gina'] || {}), parent.window['gina']);\n }\n $instance = merge( (window['gina'] || {}), $instance);\n\n registerEvents(this.plugin, events);\n \n triggerEvent(gina, proto.target, 'ginaloaded', $instance)\n }\n\n return construct\n});\n",
|
|
47
|
-
"/*!\n * Engine.IO v6.1.1\n * (c) 2014-2021 Guillermo Rauch\n * Released under the MIT License.\n */\n!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define('vendor/engine.io',e):(t=\"undefined\"!=typeof globalThis?globalThis:t||self).eio=e()}(this,(function(){\"use strict\";function t(e){return t=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&\"function\"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?\"symbol\":typeof t},t(e)}function e(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}function r(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,\"value\"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}function n(t,e,n){return e&&r(t.prototype,e),n&&r(t,n),t}function o(){return o=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t},o.apply(this,arguments)}function s(t,e){if(\"function\"!=typeof e&&null!==e)throw new TypeError(\"Super expression must either be null or a function\");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&a(t,e)}function i(t){return i=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},i(t)}function a(t,e){return a=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},a(t,e)}function u(t){if(void 0===t)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return t}function c(t,e){return!e||\"object\"!=typeof e&&\"function\"!=typeof e?u(t):e}function h(t){var e=function(){if(\"undefined\"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if(\"function\"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(t){return!1}}();return function(){var r,n=i(t);if(e){var o=i(this).constructor;r=Reflect.construct(n,arguments,o)}else r=n.apply(this,arguments);return c(this,r)}}function p(t,e,r){return p=\"undefined\"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,r){var n=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=i(t)););return t}(t,e);if(n){var o=Object.getOwnPropertyDescriptor(n,e);return o.get?o.get.call(r):o.value}},p(t,e,r||t)}var l={exports:{}};try{l.exports=\"undefined\"!=typeof XMLHttpRequest&&\"withCredentials\"in new XMLHttpRequest}catch(t){l.exports=!1}var f=l.exports,d=\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:Function(\"return this\")();function y(t){var e=t.xdomain;try{if(\"undefined\"!=typeof XMLHttpRequest&&(!e||f))return new XMLHttpRequest}catch(t){}if(!e)try{return new(d[[\"Active\"].concat(\"Object\").join(\"X\")])(\"Microsoft.XMLHTTP\")}catch(t){}}function v(t){for(var e=arguments.length,r=new Array(e>1?e-1:0),n=1;n<e;n++)r[n-1]=arguments[n];return r.reduce((function(e,r){return t.hasOwnProperty(r)&&(e[r]=t[r]),e}),{})}var m=setTimeout,g=clearTimeout;function b(t,e){e.useNativeTimers?(t.setTimeoutFn=m.bind(d),t.clearTimeoutFn=g.bind(d)):(t.setTimeoutFn=setTimeout.bind(d),t.clearTimeoutFn=clearTimeout.bind(d))}var k=w;function w(t){if(t)return function(t){for(var e in w.prototype)t[e]=w.prototype[e];return t}(t)}w.prototype.on=w.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks[\"$\"+t]=this._callbacks[\"$\"+t]||[]).push(e),this},w.prototype.once=function(t,e){function r(){this.off(t,r),e.apply(this,arguments)}return r.fn=e,this.on(t,r),this},w.prototype.off=w.prototype.removeListener=w.prototype.removeAllListeners=w.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var r,n=this._callbacks[\"$\"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks[\"$\"+t],this;for(var o=0;o<n.length;o++)if((r=n[o])===e||r.fn===e){n.splice(o,1);break}return 0===n.length&&delete this._callbacks[\"$\"+t],this},w.prototype.emit=function(t){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),r=this._callbacks[\"$\"+t],n=1;n<arguments.length;n++)e[n-1]=arguments[n];if(r){n=0;for(var o=(r=r.slice(0)).length;n<o;++n)r[n].apply(this,e)}return this},w.prototype.emitReserved=w.prototype.emit,w.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks[\"$\"+t]||[]},w.prototype.hasListeners=function(t){return!!this.listeners(t).length};var T=Object.create(null);T.open=\"0\",T.close=\"1\",T.ping=\"2\",T.pong=\"3\",T.message=\"4\",T.upgrade=\"5\",T.noop=\"6\";var S=Object.create(null);Object.keys(T).forEach((function(t){S[T[t]]=t}));for(var x={type:\"error\",data:\"parser error\"},O=\"function\"==typeof Blob||\"undefined\"!=typeof Blob&&\"[object BlobConstructor]\"===Object.prototype.toString.call(Blob),E=\"function\"==typeof ArrayBuffer,R=function(t,e,r){var n,o=t.type,s=t.data;return O&&s instanceof Blob?e?r(s):C(s,r):E&&(s instanceof ArrayBuffer||(n=s,\"function\"==typeof ArrayBuffer.isView?ArrayBuffer.isView(n):n&&n.buffer instanceof ArrayBuffer))?e?r(s):C(new Blob([s]),r):r(T[o]+(s||\"\"))},C=function(t,e){var r=new FileReader;return r.onload=function(){var t=r.result.split(\",\")[1];e(\"b\"+t)},r.readAsDataURL(t)},q=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",B=\"undefined\"==typeof Uint8Array?[]:new Uint8Array(256),L=0;L<q.length;L++)B[q.charCodeAt(L)]=L;var P,A=\"function\"==typeof ArrayBuffer,_=function(t,e){if(\"string\"!=typeof t)return{type:\"message\",data:U(t,e)};var r=t.charAt(0);return\"b\"===r?{type:\"message\",data:j(t.substring(1),e)}:S[r]?t.length>1?{type:S[r],data:t.substring(1)}:{type:S[r]}:x},j=function(t,e){if(A){var r=function(t){var e,r,n,o,s,i=.75*t.length,a=t.length,u=0;\"=\"===t[t.length-1]&&(i--,\"=\"===t[t.length-2]&&i--);var c=new ArrayBuffer(i),h=new Uint8Array(c);for(e=0;e<a;e+=4)r=B[t.charCodeAt(e)],n=B[t.charCodeAt(e+1)],o=B[t.charCodeAt(e+2)],s=B[t.charCodeAt(e+3)],h[u++]=r<<2|n>>4,h[u++]=(15&n)<<4|o>>2,h[u++]=(3&o)<<6|63&s;return c}(t);return U(r,e)}return{base64:!0,data:t}},U=function(t,e){return\"blob\"===e&&t instanceof ArrayBuffer?new Blob([t]):t},H=String.fromCharCode(30),D=function(t){s(o,t);var r=h(o);function o(t){var n;return e(this,o),(n=r.call(this)).writable=!1,b(u(n),t),n.opts=t,n.query=t.query,n.readyState=\"\",n.socket=t.socket,n}return n(o,[{key:\"onError\",value:function(t,e){var r=new Error(t);return r.type=\"TransportError\",r.description=e,p(i(o.prototype),\"emit\",this).call(this,\"error\",r),this}},{key:\"open\",value:function(){return\"closed\"!==this.readyState&&\"\"!==this.readyState||(this.readyState=\"opening\",this.doOpen()),this}},{key:\"close\",value:function(){return\"opening\"!==this.readyState&&\"open\"!==this.readyState||(this.doClose(),this.onClose()),this}},{key:\"send\",value:function(t){\"open\"===this.readyState&&this.write(t)}},{key:\"onOpen\",value:function(){this.readyState=\"open\",this.writable=!0,p(i(o.prototype),\"emit\",this).call(this,\"open\")}},{key:\"onData\",value:function(t){var e=_(t,this.socket.binaryType);this.onPacket(e)}},{key:\"onPacket\",value:function(t){p(i(o.prototype),\"emit\",this).call(this,\"packet\",t)}},{key:\"onClose\",value:function(){this.readyState=\"closed\",p(i(o.prototype),\"emit\",this).call(this,\"close\")}}]),o}(k),F=\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_\".split(\"\"),I={},M=0,W=0;function N(t){var e=\"\";do{e=F[t%64]+e,t=Math.floor(t/64)}while(t>0);return e}function X(){var t=N(+new Date);return t!==P?(M=0,P=t):t+\".\"+N(M++)}for(;W<64;W++)I[F[W]]=W;X.encode=N,X.decode=function(t){var e=0;for(W=0;W<t.length;W++)e=64*e+I[t.charAt(W)];return e};var $=X,z={encode:function(t){var e=\"\";for(var r in t)t.hasOwnProperty(r)&&(e.length&&(e+=\"&\"),e+=encodeURIComponent(r)+\"=\"+encodeURIComponent(t[r]));return e},decode:function(t){for(var e={},r=t.split(\"&\"),n=0,o=r.length;n<o;n++){var s=r[n].split(\"=\");e[decodeURIComponent(s[0])]=decodeURIComponent(s[1])}return e}},V=function(t){s(o,t);var r=h(o);function o(){var t;return e(this,o),(t=r.apply(this,arguments)).polling=!1,t}return n(o,[{key:\"doOpen\",value:function(){this.poll()}},{key:\"pause\",value:function(t){var e=this;this.readyState=\"pausing\";var r=function(){e.readyState=\"paused\",t()};if(this.polling||!this.writable){var n=0;this.polling&&(n++,this.once(\"pollComplete\",(function(){--n||r()}))),this.writable||(n++,this.once(\"drain\",(function(){--n||r()})))}else r()}},{key:\"poll\",value:function(){this.polling=!0,this.doPoll(),this.emit(\"poll\")}},{key:\"onData\",value:function(t){var e=this;(function(t,e){for(var r=t.split(H),n=[],o=0;o<r.length;o++){var s=_(r[o],e);if(n.push(s),\"error\"===s.type)break}return n})(t,this.socket.binaryType).forEach((function(t){if(\"opening\"===e.readyState&&\"open\"===t.type&&e.onOpen(),\"close\"===t.type)return e.onClose(),!1;e.onPacket(t)})),\"closed\"!==this.readyState&&(this.polling=!1,this.emit(\"pollComplete\"),\"open\"===this.readyState&&this.poll())}},{key:\"doClose\",value:function(){var t=this,e=function(){t.write([{type:\"close\"}])};\"open\"===this.readyState?e():this.once(\"open\",e)}},{key:\"write\",value:function(t){var e=this;this.writable=!1,function(t,e){var r=t.length,n=new Array(r),o=0;t.forEach((function(t,s){R(t,!1,(function(t){n[s]=t,++o===r&&e(n.join(H))}))}))}(t,(function(t){e.doWrite(t,(function(){e.writable=!0,e.emit(\"drain\")}))}))}},{key:\"uri\",value:function(){var t=this.query||{},e=this.opts.secure?\"https\":\"http\",r=\"\";!1!==this.opts.timestampRequests&&(t[this.opts.timestampParam]=$()),this.supportsBinary||t.sid||(t.b64=1),this.opts.port&&(\"https\"===e&&443!==Number(this.opts.port)||\"http\"===e&&80!==Number(this.opts.port))&&(r=\":\"+this.opts.port);var n=z.encode(t);return e+\"://\"+(-1!==this.opts.hostname.indexOf(\":\")?\"[\"+this.opts.hostname+\"]\":this.opts.hostname)+r+this.opts.path+(n.length?\"?\"+n:\"\")}},{key:\"name\",get:function(){return\"polling\"}}]),o}(D);function G(){}var J=null!=new y({xdomain:!1}).responseType,K=function(t){s(i,t);var r=h(i);function i(t){var n;if(e(this,i),n=r.call(this,t),\"undefined\"!=typeof location){var o=\"https:\"===location.protocol,s=location.port;s||(s=o?\"443\":\"80\"),n.xd=\"undefined\"!=typeof location&&t.hostname!==location.hostname||s!==t.port,n.xs=t.secure!==o}var a=t&&t.forceBase64;return n.supportsBinary=J&&!a,n}return n(i,[{key:\"request\",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return o(t,{xd:this.xd,xs:this.xs},this.opts),new Q(this.uri(),t)}},{key:\"doWrite\",value:function(t,e){var r=this,n=this.request({method:\"POST\",data:t});n.on(\"success\",e),n.on(\"error\",(function(t){r.onError(\"xhr post error\",t)}))}},{key:\"doPoll\",value:function(){var t=this,e=this.request();e.on(\"data\",this.onData.bind(this)),e.on(\"error\",(function(e){t.onError(\"xhr poll error\",e)})),this.pollXhr=e}}]),i}(V),Q=function(t){s(o,t);var r=h(o);function o(t,n){var s;return e(this,o),b(u(s=r.call(this)),n),s.opts=n,s.method=n.method||\"GET\",s.uri=t,s.async=!1!==n.async,s.data=void 0!==n.data?n.data:null,s.create(),s}return n(o,[{key:\"create\",value:function(){var t=this,e=v(this.opts,\"agent\",\"pfx\",\"key\",\"passphrase\",\"cert\",\"ca\",\"ciphers\",\"rejectUnauthorized\",\"autoUnref\");e.xdomain=!!this.opts.xd,e.xscheme=!!this.opts.xs;var r=this.xhr=new y(e);try{r.open(this.method,this.uri,this.async);try{if(this.opts.extraHeaders)for(var n in r.setDisableHeaderCheck&&r.setDisableHeaderCheck(!0),this.opts.extraHeaders)this.opts.extraHeaders.hasOwnProperty(n)&&r.setRequestHeader(n,this.opts.extraHeaders[n])}catch(t){}if(\"POST\"===this.method)try{r.setRequestHeader(\"Content-type\",\"text/plain;charset=UTF-8\")}catch(t){}try{r.setRequestHeader(\"Accept\",\"*/*\")}catch(t){}\"withCredentials\"in r&&(r.withCredentials=this.opts.withCredentials),this.opts.requestTimeout&&(r.timeout=this.opts.requestTimeout),r.onreadystatechange=function(){4===r.readyState&&(200===r.status||1223===r.status?t.onLoad():t.setTimeoutFn((function(){t.onError(\"number\"==typeof r.status?r.status:0)}),0))},r.send(this.data)}catch(e){return void this.setTimeoutFn((function(){t.onError(e)}),0)}\"undefined\"!=typeof document&&(this.index=o.requestsCount++,o.requests[this.index]=this)}},{key:\"onSuccess\",value:function(){this.emit(\"success\"),this.cleanup()}},{key:\"onData\",value:function(t){this.emit(\"data\",t),this.onSuccess()}},{key:\"onError\",value:function(t){this.emit(\"error\",t),this.cleanup(!0)}},{key:\"cleanup\",value:function(t){if(void 0!==this.xhr&&null!==this.xhr){if(this.xhr.onreadystatechange=G,t)try{this.xhr.abort()}catch(t){}\"undefined\"!=typeof document&&delete o.requests[this.index],this.xhr=null}}},{key:\"onLoad\",value:function(){var t=this.xhr.responseText;null!==t&&this.onData(t)}},{key:\"abort\",value:function(){this.cleanup()}}]),o}(k);if(Q.requestsCount=0,Q.requests={},\"undefined\"!=typeof document)if(\"function\"==typeof attachEvent)attachEvent(\"onunload\",Y);else if(\"function\"==typeof addEventListener){addEventListener(\"onpagehide\"in d?\"pagehide\":\"unload\",Y,!1)}function Y(){for(var t in Q.requests)Q.requests.hasOwnProperty(t)&&Q.requests[t].abort()}var Z=\"function\"==typeof Promise&&\"function\"==typeof Promise.resolve?function(t){return Promise.resolve().then(t)}:function(t,e){return e(t,0)},tt=d.WebSocket||d.MozWebSocket,et=\"undefined\"!=typeof navigator&&\"string\"==typeof navigator.product&&\"reactnative\"===navigator.product.toLowerCase(),rt=function(t){s(o,t);var r=h(o);function o(t){var n;return e(this,o),(n=r.call(this,t)).supportsBinary=!t.forceBase64,n}return n(o,[{key:\"doOpen\",value:function(){if(this.check()){var t=this.uri(),e=this.opts.protocols,r=et?{}:v(this.opts,\"agent\",\"perMessageDeflate\",\"pfx\",\"key\",\"passphrase\",\"cert\",\"ca\",\"ciphers\",\"rejectUnauthorized\",\"localAddress\",\"protocolVersion\",\"origin\",\"maxPayload\",\"family\",\"checkServerIdentity\");this.opts.extraHeaders&&(r.headers=this.opts.extraHeaders);try{this.ws=et?new tt(t,e,r):e?new tt(t,e):new tt(t)}catch(t){return this.emit(\"error\",t)}this.ws.binaryType=this.socket.binaryType||\"arraybuffer\",this.addEventListeners()}}},{key:\"addEventListeners\",value:function(){var t=this;this.ws.onopen=function(){t.opts.autoUnref&&t.ws._socket.unref(),t.onOpen()},this.ws.onclose=this.onClose.bind(this),this.ws.onmessage=function(e){return t.onData(e.data)},this.ws.onerror=function(e){return t.onError(\"websocket error\",e)}}},{key:\"write\",value:function(t){var e=this;this.writable=!1;for(var r=function(r){var n=t[r],o=r===t.length-1;R(n,e.supportsBinary,(function(t){try{e.ws.send(t)}catch(t){}o&&Z((function(){e.writable=!0,e.emit(\"drain\")}),e.setTimeoutFn)}))},n=0;n<t.length;n++)r(n)}},{key:\"doClose\",value:function(){void 0!==this.ws&&(this.ws.close(),this.ws=null)}},{key:\"uri\",value:function(){var t=this.query||{},e=this.opts.secure?\"wss\":\"ws\",r=\"\";this.opts.port&&(\"wss\"===e&&443!==Number(this.opts.port)||\"ws\"===e&&80!==Number(this.opts.port))&&(r=\":\"+this.opts.port),this.opts.timestampRequests&&(t[this.opts.timestampParam]=$()),this.supportsBinary||(t.b64=1);var n=z.encode(t);return e+\"://\"+(-1!==this.opts.hostname.indexOf(\":\")?\"[\"+this.opts.hostname+\"]\":this.opts.hostname)+r+this.opts.path+(n.length?\"?\"+n:\"\")}},{key:\"check\",value:function(){return!(!tt||\"__initialize\"in tt&&this.name===o.prototype.name)}},{key:\"name\",get:function(){return\"websocket\"}}]),o}(D),nt={websocket:rt,polling:K},ot=/^(?:(?![^:@]+:[^:@\\/]*@)(http|https|ws|wss):\\/\\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)/,st=[\"source\",\"protocol\",\"authority\",\"userInfo\",\"user\",\"password\",\"host\",\"port\",\"relative\",\"path\",\"directory\",\"file\",\"query\",\"anchor\"],it=function(t){var e=t,r=t.indexOf(\"[\"),n=t.indexOf(\"]\");-1!=r&&-1!=n&&(t=t.substring(0,r)+t.substring(r,n).replace(/:/g,\";\")+t.substring(n,t.length));for(var o,s,i=ot.exec(t||\"\"),a={},u=14;u--;)a[st[u]]=i[u]||\"\";return-1!=r&&-1!=n&&(a.source=e,a.host=a.host.substring(1,a.host.length-1).replace(/;/g,\":\"),a.authority=a.authority.replace(\"[\",\"\").replace(\"]\",\"\").replace(/;/g,\":\"),a.ipv6uri=!0),a.pathNames=function(t,e){var r=/\\/{2,9}/g,n=e.replace(r,\"/\").split(\"/\");\"/\"!=e.substr(0,1)&&0!==e.length||n.splice(0,1);\"/\"==e.substr(e.length-1,1)&&n.splice(n.length-1,1);return n}(0,a.path),a.queryKey=(o=a.query,s={},o.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,(function(t,e,r){e&&(s[e]=r)})),s),a};var at=function(r){s(a,r);var i=h(a);function a(r){var n,s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e(this,a),n=i.call(this),r&&\"object\"===t(r)&&(s=r,r=null),r?(r=it(r),s.hostname=r.host,s.secure=\"https\"===r.protocol||\"wss\"===r.protocol,s.port=r.port,r.query&&(s.query=r.query)):s.host&&(s.hostname=it(s.host).host),b(u(n),s),n.secure=null!=s.secure?s.secure:\"undefined\"!=typeof location&&\"https:\"===location.protocol,s.hostname&&!s.port&&(s.port=n.secure?\"443\":\"80\"),n.hostname=s.hostname||(\"undefined\"!=typeof location?location.hostname:\"localhost\"),n.port=s.port||(\"undefined\"!=typeof location&&location.port?location.port:n.secure?\"443\":\"80\"),n.transports=s.transports||[\"polling\",\"websocket\"],n.readyState=\"\",n.writeBuffer=[],n.prevBufferLen=0,n.opts=o({path:\"/engine.io\",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:\"t\",rememberUpgrade:!1,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!0},s),n.opts.path=n.opts.path.replace(/\\/$/,\"\")+\"/\",\"string\"==typeof n.opts.query&&(n.opts.query=z.decode(n.opts.query)),n.id=null,n.upgrades=null,n.pingInterval=null,n.pingTimeout=null,n.pingTimeoutTimer=null,\"function\"==typeof addEventListener&&(n.opts.closeOnBeforeunload&&addEventListener(\"beforeunload\",(function(){n.transport&&(n.transport.removeAllListeners(),n.transport.close())}),!1),\"localhost\"!==n.hostname&&(n.offlineEventListener=function(){n.onClose(\"transport close\")},addEventListener(\"offline\",n.offlineEventListener,!1))),n.open(),n}return n(a,[{key:\"createTransport\",value:function(t){var e=function(t){var e={};for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}(this.opts.query);e.EIO=4,e.transport=t,this.id&&(e.sid=this.id);var r=o({},this.opts.transportOptions[t],this.opts,{query:e,socket:this,hostname:this.hostname,secure:this.secure,port:this.port});return new nt[t](r)}},{key:\"open\",value:function(){var t,e=this;if(this.opts.rememberUpgrade&&a.priorWebsocketSuccess&&-1!==this.transports.indexOf(\"websocket\"))t=\"websocket\";else{if(0===this.transports.length)return void this.setTimeoutFn((function(){e.emitReserved(\"error\",\"No transports available\")}),0);t=this.transports[0]}this.readyState=\"opening\";try{t=this.createTransport(t)}catch(t){return this.transports.shift(),void this.open()}t.open(),this.setTransport(t)}},{key:\"setTransport\",value:function(t){var e=this;this.transport&&this.transport.removeAllListeners(),this.transport=t,t.on(\"drain\",this.onDrain.bind(this)).on(\"packet\",this.onPacket.bind(this)).on(\"error\",this.onError.bind(this)).on(\"close\",(function(){e.onClose(\"transport close\")}))}},{key:\"probe\",value:function(t){var e=this,r=this.createTransport(t),n=!1;a.priorWebsocketSuccess=!1;var o=function(){n||(r.send([{type:\"ping\",data:\"probe\"}]),r.once(\"packet\",(function(t){if(!n)if(\"pong\"===t.type&&\"probe\"===t.data){if(e.upgrading=!0,e.emitReserved(\"upgrading\",r),!r)return;a.priorWebsocketSuccess=\"websocket\"===r.name,e.transport.pause((function(){n||\"closed\"!==e.readyState&&(p(),e.setTransport(r),r.send([{type:\"upgrade\"}]),e.emitReserved(\"upgrade\",r),r=null,e.upgrading=!1,e.flush())}))}else{var o=new Error(\"probe error\");o.transport=r.name,e.emitReserved(\"upgradeError\",o)}})))};function s(){n||(n=!0,p(),r.close(),r=null)}var i=function(t){var n=new Error(\"probe error: \"+t);n.transport=r.name,s(),e.emitReserved(\"upgradeError\",n)};function u(){i(\"transport closed\")}function c(){i(\"socket closed\")}function h(t){r&&t.name!==r.name&&s()}var p=function(){r.removeListener(\"open\",o),r.removeListener(\"error\",i),r.removeListener(\"close\",u),e.off(\"close\",c),e.off(\"upgrading\",h)};r.once(\"open\",o),r.once(\"error\",i),r.once(\"close\",u),this.once(\"close\",c),this.once(\"upgrading\",h),r.open()}},{key:\"onOpen\",value:function(){if(this.readyState=\"open\",a.priorWebsocketSuccess=\"websocket\"===this.transport.name,this.emitReserved(\"open\"),this.flush(),\"open\"===this.readyState&&this.opts.upgrade&&this.transport.pause)for(var t=0,e=this.upgrades.length;t<e;t++)this.probe(this.upgrades[t])}},{key:\"onPacket\",value:function(t){if(\"opening\"===this.readyState||\"open\"===this.readyState||\"closing\"===this.readyState)switch(this.emitReserved(\"packet\",t),this.emitReserved(\"heartbeat\"),t.type){case\"open\":this.onHandshake(JSON.parse(t.data));break;case\"ping\":this.resetPingTimeout(),this.sendPacket(\"pong\"),this.emitReserved(\"ping\"),this.emitReserved(\"pong\");break;case\"error\":var e=new Error(\"server error\");e.code=t.data,this.onError(e);break;case\"message\":this.emitReserved(\"data\",t.data),this.emitReserved(\"message\",t.data)}}},{key:\"onHandshake\",value:function(t){this.emitReserved(\"handshake\",t),this.id=t.sid,this.transport.query.sid=t.sid,this.upgrades=this.filterUpgrades(t.upgrades),this.pingInterval=t.pingInterval,this.pingTimeout=t.pingTimeout,this.onOpen(),\"closed\"!==this.readyState&&this.resetPingTimeout()}},{key:\"resetPingTimeout\",value:function(){var t=this;this.clearTimeoutFn(this.pingTimeoutTimer),this.pingTimeoutTimer=this.setTimeoutFn((function(){t.onClose(\"ping timeout\")}),this.pingInterval+this.pingTimeout),this.opts.autoUnref&&this.pingTimeoutTimer.unref()}},{key:\"onDrain\",value:function(){this.writeBuffer.splice(0,this.prevBufferLen),this.prevBufferLen=0,0===this.writeBuffer.length?this.emitReserved(\"drain\"):this.flush()}},{key:\"flush\",value:function(){\"closed\"!==this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length&&(this.transport.send(this.writeBuffer),this.prevBufferLen=this.writeBuffer.length,this.emitReserved(\"flush\"))}},{key:\"write\",value:function(t,e,r){return this.sendPacket(\"message\",t,e,r),this}},{key:\"send\",value:function(t,e,r){return this.sendPacket(\"message\",t,e,r),this}},{key:\"sendPacket\",value:function(t,e,r,n){if(\"function\"==typeof e&&(n=e,e=void 0),\"function\"==typeof r&&(n=r,r=null),\"closing\"!==this.readyState&&\"closed\"!==this.readyState){(r=r||{}).compress=!1!==r.compress;var o={type:t,data:e,options:r};this.emitReserved(\"packetCreate\",o),this.writeBuffer.push(o),n&&this.once(\"flush\",n),this.flush()}}},{key:\"close\",value:function(){var t=this,e=function(){t.onClose(\"forced close\"),t.transport.close()},r=function r(){t.off(\"upgrade\",r),t.off(\"upgradeError\",r),e()},n=function(){t.once(\"upgrade\",r),t.once(\"upgradeError\",r)};return\"opening\"!==this.readyState&&\"open\"!==this.readyState||(this.readyState=\"closing\",this.writeBuffer.length?this.once(\"drain\",(function(){t.upgrading?n():e()})):this.upgrading?n():e()),this}},{key:\"onError\",value:function(t){a.priorWebsocketSuccess=!1,this.emitReserved(\"error\",t),this.onClose(\"transport error\",t)}},{key:\"onClose\",value:function(t,e){\"opening\"!==this.readyState&&\"open\"!==this.readyState&&\"closing\"!==this.readyState||(this.clearTimeoutFn(this.pingTimeoutTimer),this.transport.removeAllListeners(\"close\"),this.transport.close(),this.transport.removeAllListeners(),\"function\"==typeof removeEventListener&&removeEventListener(\"offline\",this.offlineEventListener,!1),this.readyState=\"closed\",this.id=null,this.emitReserved(\"close\",t,e),this.writeBuffer=[],this.prevBufferLen=0)}},{key:\"filterUpgrades\",value:function(t){for(var e=[],r=0,n=t.length;r<n;r++)~this.transports.indexOf(t[r])&&e.push(t[r]);return e}}]),a}(k);at.protocol=4;return function(t,e){return new at(t,e)}}));\n//# sourceMappingURL=engine.io.min.js.map\n;\n",
|
|
48
|
-
"function BindingHelper(handlerContext) {\n \n var self = {};\n if ( typeof(handlerContext) != 'undefined' ) {\n self = handlerContext\n }\n \n /**\n * process bindings\n * \n * e.g.:\n * result.bindings = \n * [\n * // close current popin\n * {\n * call: 'closeActivePopin'\n * },\n * // mark notification as read\n * {\n * call: 'onNotification',\n * payload: {\n * id: obj.notificationId,\n * action: 'mark-as-read'\n * }\n * },\n * {\n * handler: 'DocumentHandler', // targeting another handler\n * call: 'notify' // this method must be public\n * }\n * ]\n * \n * @param {array} bindings\n * @param {number} [len]\n * @param {number} [i] \n */\n self.process = function(bindings, len, i) {\n // handle errors first\n if ( typeof(bindings) == 'undefined' || !Array.isArray(bindings) ) {\n throw new Error('`bindings` must be a defined array')\n }\n if ( typeof(len) == 'undefined' ) {\n len = bindings.length;\n i = 0;\n }\n \n if ( !bindings[i] )\n return;\n \n var handleObject = bindings[i];\n if ( typeof(handleObject.call) == 'undefined' )\n throw new Error('`bindings.['+ i +'].call` is required !');\n \n if ( typeof(self[ handleObject.call ]) != 'function' ) \n throw new Error('`bindingContext.'+ handleObject.call +'` is not a function');\n \n // process the collection\n var hCall = handleObject.call;\n delete handleObject.call;\n \n try {\n \n // !! targeted handler instance must be exposed to the window object\n if ( typeof(handleObject.handler) != 'undefined' ) {\n \n if ( !window[ handleObject.handler ] )\n throw new Error('`'+ handleObject.handler +'` could not be reached. You must expose it to the `window` do object before any call.');\n \n var hHandler = handleObject.handler;\n delete handleObject.handler;\n \n window[ hHandler ].apply( this, Object.values(handleObject) );\n //restore\n handleObject.handler = hHandler\n } else { // by default, will go to main handler or the one listening to xhr results\n self[ hCall ].apply( this, Object.values(handleObject) );\n } \n \n //restore\n handleObject.call = hCall;\n } catch (err) {\n console.error('BindingHelper encountered error while trying to execute `'+ hCall +'`' + err.stack || err);\n }\n \n self.process(bindings, len, i+1)\n }\n \n \n return self\n}\n// Publish as AMD module\ndefine( 'helpers/binding',[],function() { return BindingHelper });\n",
|
|
49
|
-
"define('gina/link', [ 'require', 'jquery', 'vendor/uuid','utils/merge', 'utils/events' ], function (require) {\n\n var $ = require('jquery');\n $.noConflict();\n var uuid = require('vendor/uuid');\n var merge = require('utils/merge');\n\n require('utils/events'); // events\n \n /**\n * Gina Link Handler\n *\n * @param {object} options\n * */\n function Link(options) {\n\n this.plugin = 'link';\n\n var events = ['loaded', 'ready', 'open', 'close', 'destroy', 'success', 'error', 'progress'];\n registerEvents(this.plugin, events);\n\n var self = { // local use only\n 'options' : {\n 'url' : undefined,\n 'class': 'gina-link-default'\n },\n authorizedEvents : ['ready', 'success', 'error'],\n events: {}\n };\n\n var instance = {\n plugin : this.plugin,\n id : 'gina-links-' + uuid.v4(),\n on : on,\n eventData : {},\n\n '$links' : {},\n target : document, // by default\n isReady : false,\n initialized : false\n };\n\n // link proto\n var $link = { // is on main `gina-links` container (first level)\n 'plugin' : this.plugin,\n 'on' : on,\n 'eventData' : {},\n 'target' : document, // by default\n\n 'url' : null,\n 'request' : null,\n '$forms' : []\n };\n\n\n\n // XML Request\n var xhr = null;\n \n /**\n * XML Request options\n * */\n var xhrOptions = {\n 'url' : '',\n 'method' : 'GET',\n 'isSynchrone' : false,\n 'withCredentials': true, // if should be enabled under a trusted env\n 'headers' : {\n // cross domain is enabled by default, but you need to setup `Access-Control-Allow-Origin`\n 'X-Requested-With': 'XMLHttpRequest' // to set isXMLRequest == true && in case of cross domain origin\n\n }\n };\n\n var registeredLinks = [];\n\n \n\n var proxyClick = function($childNode, $el, evt) {\n\n addListener(gina, $childNode, 'click', function(e) {\n cancelEvent(e);\n\n triggerEvent(gina, $el, evt);\n });\n }\n \n var getLinkById = function(id) { \n return ( typeof(instance.$links[id]) != 'undefined' ) ? instance.$links[id] : null;\n }\n \n var getLinkByUrl = function(url) {\n var $link = null;\n \n for (var p in gina.link.$links) {\n if ( typeof(gina.link.$links[p].url) != 'undefined' && gina.link.$links[p].url == url ) {\n $link = gina.link.$links[p];\n break;\n }\n }\n \n return $link;\n }\n \n \n\n /**\n * linkRequest\n *\n * @param {string} url\n * @param {object} [options]\n * */\n function linkRequest(url, options) {\n\n // link object\n var $link = getLinkByUrl(url);\n var id = $link.id;\n \n \n // link element\n var $el = document.getElementById(id) || null;\n \n var hLinkIsRequired = null; \n // forward callback to HTML data event attribute through `hform` status\n hLinkIsRequired = ( $el.getAttribute('data-gina-link-event-on-success') || $el.getAttribute('data-gina-link-event-on-error') ) ? true : false;\n // success -> data-gina-form-event-on-submit-success\n // error -> data-gina-form-event-on-submit-error\n if (hLinkIsRequired)\n listenToXhrEvents($link);\n\n // if ( $el == null ) {\n\n // //var className = $link.options.class +' '+ id;\n // $el = document.createElement('a');\n // $el.setAttribute('id', id);\n // //$el.setAttribute('class', className);\n // instance.target.firstChild.appendChild($el);\n // }\n\n if ( typeof(options) == 'undefined' ) {\n options = xhrOptions;\n } else {\n options = merge(options, xhrOptions);\n }\n \n if ( /^(http|https)\\:/.test(url) && !new RegExp('^' + window.location.protocol + '//'+ window.location.host).test(url) ) {\n // is request from same domain ?\n //options.headers['Origin'] = window.protocol+'//'+window.location.host;\n //options.headers['Origin'] = '*';\n //options.headers['Host'] = 'https://freelancer-app.fr.local:3154';\n var isSameDomain = ( new RegExp(window.location.hostname).test(url) ) ? true : false;\n if (!isSameDomain) {\n // proxy external urls\n // TODO - instead of using `cors.io`, try to intégrate a local CORS proxy similar to : http://oskarhane.com/avoid-cors-with-nginx-proxy_pass/\n //url = url.match(/^(https|http)\\:/)[0] + '//cors.io/?' + url;\n url = url.match(/^(https|http)\\:/)[0] + '//corsacme.herokuapp.com/?'+ url;\n //delete options.headers['X-Requested-With']\n } \n }\n options.url = url;\n // updating link options\n if ($link && typeof($link.options) != 'undefined')\n options = merge($link.options, options);\n\n\n if ( options.withCredentials ) { // Preflighted requests \n if ('withCredentials' in xhr) {\n // XHR for Chrome/Firefox/Opera/Safari.\n if (options.isSynchrone) {\n xhr.open(options.method, options.url, options.isSynchrone)\n } else {\n xhr.open(options.method, options.url)\n }\n } else if ( typeof XDomainRequest != 'undefined' ) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n xhr.open(options.method, options.url);\n } else {\n // CORS not supported.\n xhr = null;\n var result = 'CORS not supported: the server is missing the header `\"Access-Control-Allow-Credentials\": true` ';\n triggerEvent(gina, $el, 'error.' + id, result)\n }\n } else { // simple requests\n \n if (options.isSynchrone) {\n xhr.open(options.method, options.url, options.isSynchrone)\n } else {\n xhr.open(options.method, options.url)\n }\n }\n\n \n\n if (!xhr)\n throw new Error('No `xhr` object initiated');\n \n \n options.$link = $link;\n //xhr = handleXhr(xhr, $el, options);\n handleXhr(xhr, $el, options, require);\n // sending\n xhr.send();\n }\n\n // var listenToXhrEvents = function($link) {\n \n // //data-gina-link-event-on-success\n // var htmlSuccesEventCallback = $link.target.getAttribute('data-gina-link-event-on-success') || null;\n // if (htmlSuccesEventCallback != null) {\n \n // if ( /\\((.*)\\)/.test(htmlSuccesEventCallback) ) {\n // eval(htmlSuccesEventCallback)\n // } else {\n // $link.on('success.hlink', window[htmlSuccesEventCallback])\n // }\n // }\n \n // //data-gina-link-event-on-error\n // var htmlErrorEventCallback = $link.target.getAttribute('data-gina-link-event-on-error') || null;\n // if (htmlErrorEventCallback != null) {\n // if ( /\\((.*)\\)/.test(htmlErrorEventCallback) ) {\n // eval(htmlErrorEventCallback)\n // } else {\n // $link.on('error.hlink', window[htmlErrorEventCallback])\n // }\n // }\n // }\n \n \n\n \n function registerLink($link, options) {\n \n if ( typeof(options) != 'object' ) {\n throw new Error('`options` must be an object')\n }\n \n $link.options = merge(options, self.options); \n \n // link element\n var id = $link.id;\n var $el = document.getElementById(id) || null;\n \n if ( typeof(instance.$links[$link.id]) == 'undefined' ) { \n\n \n\n if ( registeredLinks.indexOf($link.id) > -1 ) {\n throw new Error('`link '+$link.id+'` already exists !')\n }\n \n \n if (!gina.events[evt]) {\n \n \n \n // attach click events\n addListener(gina, $el, evt, function(e) {\n cancelEvent(e);\n\n var $localLink = getLinkById(e.target.id)\n // loading & binding link \n var localUrl = $localLink.url;\n\n // Non-Preflighted requests \n if ( typeof($localLink.options.isSynchrone) == 'undefined' ) {\n $localLink.options.isSynchrone = false;\n }\n if ( typeof($localLink.options.withCredentials) == 'undefined' ) {\n $localLink.options.withCredentials = false\n }\n \n linkRequest(localUrl, $localLink.options); \n \n //delete gina.events[ $localLink.id ];\n //removeListener(gina, event.target, event.type)\n });\n\n\n\n // bind child elements\n var childNodes = $el.childNodes;\n var l = 0; lLen = childNodes.length;\n if (lLen > 0) {\n for(; l < lLen; ++l) {\n if (typeof (childNodes[l].tagName) != 'undefined') {\n proxyClick(childNodes[l], $el, evt)\n }\n }\n }\n }\n \n \n\n \n $link.request = linkRequest;\n $link.getLinkById = getLinkById;\n $link.getLinkByUrl = getLinkByUrl;\n \n instance.$links[$link.id] = $link;\n \n \n \n }\n }\n \n /**\n * bindLinks\n *\n * @param {object} $target - DOM element\n * @param {object} [options]\n * */\n var bindLinks = function($target, options) {\n \n var id = null;\n if ( typeof($target) == 'undefined' ) {\n $target = instance.target;\n id = instance.id;\n }\n \n // binding form elements\n var found = null\n , $el = null\n , props = null\n , $newLink = null\n , url = null\n , elId = null\n , onEvent = null\n , onclickAttribute = null\n // a\n , $a = $target.getElementsByTagName('a')\n // buttons\n //, $button = $target.getElementsByTagName('button')\n ;\n \n var i = 0, len = $a.length; \n for (; i < len; ++i) {\n found = $a[i].getAttribute('data-gina-link');\n \n if (!found) continue;\n \n $el = $a[i];\n props = {\n type: 'a',\n method: 'GET'\n };\n \n \n url = $el.getAttribute('data-gina-link-url');\n if ( typeof(url) != 'undefined' && url != null ) {\n props.url = url\n } else {\n props.url = $el.getAttribute('href')\n }\n \n \n \n \n elId = $el.getAttribute('id');\n if ( typeof(elId) == 'undefined' || elId == null || elId == '' || /popin\\.link/.test(elId) ) {\n \n // unbind popin link\n // if ( /popin\\.link/.test(elId) ) {\n \n // }\n \n elId = 'link.click.'+ 'gina-link-' + instance.id +'-'+ uuid.v4();\n } \n $el['id'] = elId;\n props.id = elId;\n evt = elId;\n $el.setAttribute('id', evt);\n \n if ($el.tagName == 'A') {\n onclickAttribute = $el.getAttribute('onclick');\n }\n\n if ( !onclickAttribute ) {\n $el.setAttribute('onclick', 'return false;')\n } else if ( typeof(onclickAttribute) != 'undefined' && !/return false/.test(onclickAttribute) ) {\n if ( /\\;$/.test(onclickAttribute) ) {\n onclickAttribute += 'return false;'\n } else {\n onclickAttribute += '; return false;'\n }\n $el.setAttribute('onclick', onclickAttribute);\n }\n \n $newLink = null;\n \n if ( typeof(instance.$links[props.id]) == 'undefined' ) { \n props.target = $el; \n $newLink = merge(props, $link); \n registerLink($newLink, options);\n }\n \n \n }\n \n }\n\n var init = function(options) {\n \n setupInstanceProto();\n instance.on('init', function(event) {\n \n // setting up AJAX\n if (window.XMLHttpRequest) { // Mozilla, Safari, ...\n xhr = new XMLHttpRequest();\n } else if (window.ActiveXObject) { // IE\n try {\n xhr = new ActiveXObject(\"Msxml2.XMLHTTP\");\n } catch (e) {\n try {\n xhr = new ActiveXObject(\"Microsoft.XMLHTTP\");\n }\n catch (e) {}\n }\n } \n \n // proxies\n // click on main document\n evt = 'click';// click proxy\n // for proxies, use linkInstance.id as target is always `document`\n addListener(gina, instance.target, evt, function(event) {\n\n if ( typeof(event.target.id) == 'undefined' ) {\n event.target.setAttribute('id', evt +'.'+ uuid.v4() );\n event.target.id = event.target.getAttribute('id')\n }\n\n \n\n if ( /^link\\.click\\./.test(event.target.id) ) {\n cancelEvent(event);\n var _evt = event.target.id;\n\n if ( new RegExp( '^link.click.gina-link-' + instance.id).test(_evt) )\n triggerEvent(gina, event.target, _evt, event.detail);\n\n }\n });\n \n if ( typeof(options) == 'undefined' ) {\n options = {}\n }\n instance.options = options;\n \n bindLinks(instance.target, options);\n gina.linkIsBinded = true;\n\n instance.isReady = true;\n gina.hasLinkHandler = true;\n gina.link = merge(gina.link, instance);\n // trigger link ready event\n triggerEvent(gina, instance.target, 'ready.' + instance.id, instance);\n });\n\n \n \n\n instance.initialized = true;\n\n return instance\n }\n \n var setupInstanceProto = function() {\n\n instance.bindLinks = bindLinks;\n instance.request = linkRequest;\n instance.getLinkById = getLinkById;\n instance.getLinkByUrl = getLinkByUrl;\n }\n \n return init(options)\n };\n\n return Link\n});\n",
|
|
50
|
-
"define('gina/popin', [ 'require', 'jquery', 'vendor/uuid','utils/merge', 'utils/routing', 'utils/events' ], function (require) {\n\n var $ = require('jquery');\n $.noConflict();\n var uuid = require('vendor/uuid');\n var merge = require('utils/merge');\n var routing = require('utils/routing');\n\n require('utils/events'); // events\n\n /**\n * Gina Popin Handler\n *\n * @param {object} options\n * */\n function Popin(options) {\n\n this.plugin = 'popin';\n\n var events = ['init', 'loaded', 'ready', 'open', 'close', 'click', 'destroy', 'success', 'error', 'progress'];\n registerEvents(this.plugin, events);\n\n var self = { // local use only\n 'options' : {\n 'name' : undefined,\n 'class': 'gina-popin-default'\n },\n authorizedEvents : ['ready', 'error'],\n events: {}\n };\n\n var instance = {\n plugin : this.plugin,\n id : 'gina-popins-' + uuid.v4(),\n on : on,\n eventData : {},\n\n '$popins' : {},\n activePopinId : null, \n getActivePopin : null, // returns the active $popin\n target : document, // by default\n isReady : false,\n initialized : false\n };\n\n // popin proto\n var $popin = { // is on main `gina-popins` container (first level)\n 'plugin' : this.plugin,\n 'on' : on,\n 'eventData' : {},\n 'target' : document, // by default\n\n 'name' : null,\n 'load' : null,\n 'loadContent' : null,\n 'open' : null,\n 'isOpen' : false,\n 'isRedirecting' : false,\n 'close' : null,\n '$forms' : [],\n 'hasForm' : false,\n '$headers' : [] // head elements for this popin\n };\n\n // imopring other plugins\n var $validatorInstance = null; // validator instance\n\n\n // XML Request\n var xhr = null;\n\n var registeredPopins = [];\n\n\n /**\n * popinCreateContainer\n *\n * Creates HTML container and add it to the DOM\n *\n *\n * */\n var popinCreateContainer = function() {\n\n // creating template\n // <div class=\"gina-popins\">\n // <div class=\"gina-popins-overlay gina-popin-is-active\"></div>\n // </div>\n var $container = document.createElement('div');\n $container.id = instance.id;\n $container.setAttribute('id', instance.id);\n $container.setAttribute('class', 'gina-popins');\n\n var $overlay = document.createElement('div');\n $overlay.setAttribute('id', 'gina-popins-overlay');\n $overlay.setAttribute('class', 'gina-popins-overlay');\n\n\n $container.appendChild( $overlay );\n\n // adding to DOM\n document.body.appendChild($container);\n\n instance.target = $container;\n instance.on = on;\n\n gina.popinContainer = instance.id;\n //gina.hasPopinHandler = true;\n }\n \n var popinGetContainer = function () {\n instance.target = document.getElementById(gina.popinContainer);\n instance.on = on;\n }\n\n var proxyClick = function($childNode, $el, evt) {\n //if ( )\n addListener(gina, $childNode, 'click', function(e) {\n cancelEvent(e);\n\n triggerEvent(gina, $el, evt);\n });\n }\n \n var getPopinById = function(id) { \n return ( typeof(instance.$popins[id]) != 'undefined' ) ? instance.$popins[id] : null;\n }\n \n var getPopinByName = function(name) {\n \n var $popin = null;\n \n for (var p in instance.$popins) {\n if ( instance.$popins[p].name === name ) {\n $popin = instance.$popins[p];\n break;\n }\n }\n \n return $popin;\n } \n \n function getActivePopin() { \n var $popin = null;\n \n for (var p in gina.popin.$popins) {\n if ( typeof(gina.popin.$popins[p].isOpen) != 'undefined' && gina.popin.$popins[p].isOpen ) {\n $popin = gina.popin.$popins[p];\n break;\n }\n }\n \n if (!$popin && gina.popin.activePopinId) {\n $popin = gina.popin.$popins[gina.popin.activePopinId]\n }\n \n return $popin;\n } \n \n\n var bindOpen = function($popin, isRouting) {\n \n isRouting = ( typeof(isRouting) != 'undefined' ) ? isRouting : false;\n \n var attr = 'data-gina-popin-name';\n var $els = getElementsByAttribute(attr);\n var $el = null, name = null;\n var url = null; \n var proceed = null, evt = null;\n var i = null, len = null;\n\n i = 0; len = $els.length;\n for (;i < len; ++i) {\n $el = $els[i];\n name = $el.getAttribute(attr);\n if ( $el.tagName == 'A' ) {\n url = $el.getAttribute('href');\n if (url == '' || url =='#' || /\\#/.test(url) ) {\n url = null\n }\n }\n\n if ( !url && typeof( $el.getAttribute('data-gina-popin-url') ) != 'undefined') {\n url = $el.getAttribute('data-gina-popin-url');\n }\n\n if (!url) {\n throw new Error('Found `data-gina-popin-name` without `url` !')\n }\n\n if ( !$el['url'] ) {\n $el['url'] = url;\n }\n\n if ( !$el['popinName'] ) {\n $el['popinName'] = name;\n }\n\n if (name == $popin.name) {\n evt = 'popin.click.'+ 'gina-popin-' + instance.id +'-'+ uuid.v4() +'-'+ name;\n $el['id'] = evt;\n $el.setAttribute( 'id', evt);\n \n if (!gina.events[evt]) {\n \n // attach click events\n addListener(gina, $el, evt, function(e) {\n cancelEvent(e);\n\n var fired = false;\n addListener(gina, $popin.target, 'loaded.'+$popin.id, function(e) {\n e.preventDefault();\n\n if (!fired) {\n fired = true;\n console.debug('active popin should be ', $popin.id);\n gina.popin.activePopinId = $popin.id;\n popinBind(e, $popin);\n if (!$popin.isOpen) { \n popinOpen($popin.name);\n } \n }\n });\n\n // loading & binding popin \n // Non-Preflighted requests\n var options = { \n isSynchrone: false,\n withCredentials: false // by default\n }; \n options = merge($popin.options, options); \n var url = this.getAttribute('data-gina-popin-url') || this.getAttribute('href');\n if (!url) {\n throw new Error('Popin `url` not defined, please check value for `data-gina-popin-url`');\n }\n popinLoad($popin.name, url, options);\n });\n\n\n\n // bind child elements\n var childNodes = $el.childNodes;\n var l = 0; lLen = childNodes.length;\n if (lLen > 0) {\n for(; l < lLen; ++l) {\n if (typeof (childNodes[l].tagName) != 'undefined') {\n proxyClick(childNodes[l], $el, evt)\n }\n }\n }\n }\n }\n\n }\n\n // proxies\n // click on main document\n evt = 'click';// click proxy\n // for proxies, use popinInstance.id as target is always `document`\n addListener(gina, document, evt, function(event) {\n \n if ( event.target.getAttribute('disabled') != null && event.target.getAttribute('disabled') != 'false' ) {\n return false;\n }\n\n if ( typeof(event.target.id) == 'undefined' ) {\n event.target.setAttribute('id', evt +'.'+ uuid.v4() );\n event.target.id = event.target.getAttribute('id')\n }\n\n if ( /^popin\\.close\\./.test(event.target.id) ) {\n cancelEvent(event);\n\n var _evt = event.target.id;\n triggerEvent(gina, event.target, _evt, event.detail);\n }\n\n if ( /^popin\\.click\\./.test(event.target.id) ) {\n cancelEvent(event);\n //console.log('popin.click !! ', event.target);\n var _evt = event.target.id; \n\n if ( new RegExp( '^popin.click.gina-popin-' + instance.id).test(_evt) )\n triggerEvent(gina, event.target, _evt, event.detail);\n }\n });\n\n gina.popinIsBinded = false\n }\n \n \n function popinBind(e, $popin) {\n \n var $el = e.target;\n var eventType = e.type;\n \n if ( \n typeof(e.detail) != 'undefined' \n && typeof(e.detail.trim) == 'function' \n ) {\n $el.innerHTML = e.detail.trim();\n }\n \n \n var register = function (type, evt, $element) {\n var isLink = $element.getAttribute('data-gina-popin-is-link');\n isLink = ( /^true$/i.test(isLink) ) ? true : false;\n if ( type == 'link' && !isLink) {\n // like a form action, so gina will not follow the href and the event will be prevented\n type = 'action';\n }\n // attach submit events\n addListener(gina, $element, evt, function(event) {\n\n cancelEvent(event);\n \n if (type != 'close') {\n \n var fired = false;\n var _evt = 'loaded.' + $popin.id;\n \n if ( typeof(gina.events[_evt]) == 'undefined' ) {\n addListener(gina, $el, _evt, function(e) {\n \n e.preventDefault();\n\n if (!fired) {\n fired = true; \n popinLoadContent(e.detail); \n }\n });\n }\n \n // Non-Preflighted requests\n var options = { \n isSynchrone: false,\n withCredentials: false\n };\n //options = merge(options, $popin.options); \n options = merge($popin.options, options); \n popinLoad($popin.name, $element.href, options);\n } \n \n removeListener(gina, event.target, event.type)\n });\n \n addListener(gina, $element, 'click', function(event) {\n cancelEvent(event);\n // ignore disabled\n if ( event.target.getAttribute('disabled') != null && event.target.getAttribute('disabled') != 'false' ) {\n return false;\n }\n // NB.: `type == 'action'` will be handled by the form validator\n if ( type == 'link' ) {\n //console.debug('This is a link', event.target);\n var linkTarget = event.target.getAttribute('target');\n if ( linkTarget != null && linkTarget != '' ) { \n var _window = window.open(linkHref, event.target.getAttribute('target'));\n // _window.onload = function onWindowLoad() {\n // var $popin = getActivePopin(); \n // triggerEvent(gina, $popin, 'loaded.' + id);\n // }\n } else { // else, inside viewbox\n // TODO - Integrate https://github.com/box/viewer.js#loading-a-simple-viewer \n triggerEvent(gina, event.target, event.currentTarget.id, $popin);\n }\n \n } /**else if ( type == 'action' ) {\n // rewrite form attributes\n //console.debug('This is an action ', event.target);\n }*/ else { // close\n \n if ( typeof(event.target.id) == 'undefined' ) {\n event.target.setAttribute('id', evt +'.'+ uuid.v4() );\n event.target.id = event.target.getAttribute('id')\n }\n \n if ( /^popin\\.close\\./.test(event.target.id) ) {\n cancelEvent(event);\n // Just in case we left the popin with a link:target = _blank\n $popin.isRedirecting = false;\n popinClose($popin.name);\n }\n \n if ( /^popin\\.click\\./.test(event.target.id) ) {\n cancelEvent(event);\n var _evt = event.target.id;\n \n if ( new RegExp( '^popin.click.gina-popin-' + instance.id).test(_evt) )\n triggerEvent(gina, event.target, _evt, event.detail);\n \n }\n } \n });\n \n };\n \n gina.popinIsBinded = true;\n \n var i = null\n , b = null\n , len = null\n ;\n // bind overlay on click\n if (!$popin.isOpen) { \n \n var $overlay = instance.target.childNodes[0];\n addListener(gina, $overlay, 'mousedown', function(event) {\n\n // don't cancel here, it will corrupt child elements behaviors such as checkboxes and radio buttons\n if ( /gina-popin-is-active/.test(event.target.className) ) {\n\n // remove listeners\n removeListener(gina, event.target, 'mousedown');\n \n // binding popin close\n var $close = []\n , $buttonsTMP = [] \n ;\n \n i = 0; \n $buttonsTMP = $el.getElementsByTagName('button');\n b = 0; len = $buttonsTMP.length;\n if ( len > 0 ) {\n for(; b < len; ++b) {\n if ( /gina-popin-close/.test($buttonsTMP[b].className) ) {\n $close[i] = $buttonsTMP[b];\n ++i;\n } \n }\n }\n \n $buttonsTMP = $el.getElementsByTagName('div');\n b = 0; len = $buttonsTMP.length;\n if ( len > 0 ) {\n for(; b < len; ++b) {\n if ( /gina-popin-close/.test($buttonsTMP[b].className) ) {\n $close[i] = $buttonsTMP[b];\n ++i\n } \n }\n }\n \n $buttonsTMP = $el.getElementsByTagName('a');\n b = 0; len = $buttonsTMP.length;\n if ( len > 0 ) {\n for(; b < len; ++b) {\n if ( /gina-popin-close/.test($buttonsTMP[b].className) ) {\n $close[i] = $buttonsTMP[b];\n ++i\n } \n }\n }\n \n b = 0; len = $close.length;\n for (; b < len; ++b) {\n let $el = $close[b];\n let eId = $el.getAttribute('id');\n for (let e = 0, eLen = events.length; e < eLen; e++) {\n let evt = events[e];\n if ( typeof(gina.events[ evt ]) != 'undefined' && gina.events[ evt ] == eId ) {\n removeListener(gina, $el, evt);\n }\n if ( typeof(gina.events[ eId ]) != 'undefined' && gina.events[ eId ] == eId ) { \n removeListener(gina, $el, eId);\n }\n \n if ( typeof(gina.events[ evt +'.'+ eId ]) != 'undefined' && gina.events[ evt +'.'+ eId ] == eId ) {\n removeListener(gina, $el, evt +'.'+ eId);\n }\n \n if ( typeof(gina.events[ evt +'.'+ eId ]) != 'undefined' && gina.events[ evt +'.'+ eId ] == evt +'.'+ eId ) {\n removeListener(gina, $el, evt +'.'+ eId);\n }\n }\n \n \n //removeListener(gina, $close[b], $close[b].getAttribute('id') );\n }\n \n // div with click\n // var $elTMP = $form.target.getElementsByTagName('div');\n // if ( $elTMP.length > 0 ) {\n // for(let i = 0, len = $elTMP.length; i < len; ++i) {\n // $els.push( $elTMP[i] )\n // }\n // }\n // // label with click\n // $elTMP = $form.target.getElementsByTagName('label');\n // if ( $elTMP.length > 0 ) {\n // for(let i = 0, len = $elTMP.length; i < len; ++i) {\n // $els.push( $elTMP[i] )\n // }\n // }\n \n // Just in case we left the popin with a link:target = _blank\n $popin.isRedirecting = false;\n popinClose($popin.name);\n }\n \n });\n }\n // detecting form in popin\n if ( /<form/i.test($el.innerHTML) && typeof($validatorInstance) != 'undefined' && $validatorInstance ) {\n $popin.hasForm = true;\n }\n \n // binding popin close & links (& its target attributes)\n var $close = []\n , $buttonsTMP = []\n , $link = []\n ;\n\n $buttonsTMP = $el.getElementsByTagName('button');\n i = 0; b = 0; len = $buttonsTMP.length;\n if ( $buttonsTMP.length > 0 ) {\n for(; b < len; ++b) {\n if ( /gina-popin-close/.test($buttonsTMP[b].className) ) {\n $close[i] = $buttonsTMP[b];\n ++i\n } \n }\n }\n\n $buttonsTMP = $el.getElementsByTagName('div');\n b = 0; len = $buttonsTMP.length;\n if ( len > 0 ) {\n for(; b < len; ++b) {\n if ( /gina-popin-close/.test($buttonsTMP[b].className) ) {\n $close[i] = $buttonsTMP[b];\n ++i;\n } \n }\n }\n\n $buttonsTMP = $el.getElementsByTagName('a');\n b = 0; len = $buttonsTMP.length;\n if ( len > 0 ) {\n for(; b < len; ++b) {\n if ( /gina-popin-close/.test($buttonsTMP[b].className) ) {\n $close[i] = $buttonsTMP[b];\n ++i;\n continue\n }\n \n if ( \n typeof($buttonsTMP[b]) != 'undefined' \n && !/(\\#|\\#.*)$/.test($buttonsTMP[b].href) // ignore href=\"#\" \n // ignore href already bindded byr formValidator or the user \n && !$buttonsTMP[b].id\n ||\n typeof($buttonsTMP[b]) != 'undefined'\n && !/(\\#|\\#.*)$/.test($buttonsTMP[b].href) // ignore href=\"#\" \n && !/^(click\\.|popin\\.link)/.test($buttonsTMP[b].id)\n ) {\n $link.push($buttonsTMP[b]);\n continue\n }\n }\n }\n \n var onclickAttribute = null, evt = null;\n // close events\n b = 0; len = $close.length;\n for (; b < len; ++b) {\n if ($close[b].tagName == 'A') {\n onclickAttribute = $close[b].getAttribute('onclick');\n }\n\n if ( !onclickAttribute ) {\n $close[b].setAttribute('onclick', 'return false;')\n } else if ( typeof(onclickAttribute) != 'undefined' && !/return false/.test(onclickAttribute) ) {\n if ( /\\;$/.test(onclickAttribute) ) {\n onclickAttribute += 'return false;'\n } else {\n onclickAttribute += '; return false;'\n }\n }\n\n if (!$close[b]['id']) {\n\n evt = 'popin.close.'+ uuid.v4();\n $close[b]['id'] = evt;\n $close[b].setAttribute( 'id', evt);\n\n } else {\n evt = $close[b]['id'];\n } \n\n\n if ( typeof(gina.events[evt]) == 'undefined' || gina.events[evt] != $close[b].id ) {\n register('close', evt, $close[b])\n }\n }\n \n // link events\n i = 0; len = $link.length;\n var _form = null, f = null, fLen = null;\n var inheritedData = {}, _formData = null;\n var domParserObject = new DOMParser()\n , currentId = null\n , found = null\n , aHref = null\n , isSubmitLink = null\n , isLink = null\n ;\n \n for (; i < len; ++i) {\n // if is disabled, stop propagation\n if ( $link[i].getAttribute('disabled') != null ) {\n continue;\n }\n \n $link[i]['id'] = ( /^null$/i.test($link[i].getAttribute('id')) ) ? null : $link[i].getAttribute('id'); \n if (!$link[i]['id'] || !/^popin\\.link/.test($link[i]['id']) || !/^popin\\.click/.test($link[i]['id']) ) {\n \n // just in case\n isLink = true;\n aHref = $link[i].getAttribute('href');\n if (!aHref || aHref == '' || aHref == '#' ) {\n if (aHref != '#')\n $link[i].setAttribute('href', '#');\n isLink = false;\n }\n // link or action ? \n if (/^null$/i.test($link[i]['id'])) {\n if ( isLink ) {\n evt = 'popin.link.' + uuid.v4();\n $link[i].setAttribute('data-gina-popin-is-link', true);\n } else {\n evt = 'popin.click.' + uuid.v4();\n $link[i].setAttribute('data-gina-popin-is-link', false);\n }\n } else {\n evt = $link[i]['id'];\n }\n \n $link[i]['id'] = evt; \n $link[i].setAttribute( 'id', evt);\n \n } else {\n evt = $link[i]['id'];\n }\n \n // ignore `isSubmitLink == true`\n // will be handled by validator\n isSubmitLink = $link[i].getAttribute('data-gina-form-submit');\n isSubmitLink = ( isSubmitLink && /^true$/i.test(isSubmitLink) ) ? true : false; \n if (isSubmitLink) {\n continue;\n }\n \n \n if ( !/^(null|\\s*)$/.test($link[i].getAttribute('href')) ) {\n addListener(gina, $link[i], 'click', function(linkEvent) {\n linkEvent.preventDefault();\n \n $popin.isRedirecting = true;\n \n if ($popin.hasForm) {\n // Experimental - inheritedData\n // Inhertitance from previously request: merging datas with current form context\n // TODO - Get the inhereted data from LMDB Database using the form CSRF\n _form = $popin.target.getElementsByTagName('FORM');\n f = 0; fLen = _form.length;\n for (; f < fLen; ++f) {\n // check if current link is in form\n currentId = linkEvent.currentTarget.id;\n found = domParserObject.parseFromString(_form.item(f).innerHTML, 'text/html').getElementById(currentId) || false;\n if ( found ) {\n _formData = _form[f].getAttribute('data-gina-form-inherits-data') || null;\n // mergin GET data\n inheritedData = merge(inheritedData, JSON.parse(decodeURIComponent(_formData)));\n }\n }\n \n // has already params ?\n if ( inheritedData.count() > 0 ) {\n if ( /\\?/.test(linkEvent.currentTarget.href) ) {\n linkEvent.currentTarget.href += '&inheritedData=' + encodeURIComponent(JSON.stringify(inheritedData));\n } else {\n linkEvent.currentTarget.href += '?inheritedData=' + encodeURIComponent(JSON.stringify(inheritedData));\n }\n } \n }\n })\n }\n\n if ( typeof(gina.events[evt]) == 'undefined' || gina.events[evt] != $link[i].id ) {\n register('link', evt, $link[i])\n }\n \n \n } // EO for(; i < len; ++i) \n \n // bind with formValidator if forms are found\n if ($popin.hasForm) {\n var _id = null;\n var $forms = $el.getElementsByTagName('form');\n i = 0; len = $forms.length;\n for(; i < len; ++i) {\n\n if ( !$forms[i]['id'] || typeof($forms[i]) != 'string' ) {\n _id = $forms[i].getAttribute('id') || 'form.' + uuid.v4();\n $forms[i].setAttribute('id', _id);// just in case\n $forms[i]['id'] = _id\n } else {\n _id = $forms[i]['id']\n }\n\n //console.debug('pushing ', _id, $forms[i]['id'], typeof($forms[i]['id']), $forms[i].getAttribute('id'));\n if ($popin['$forms'].indexOf(_id) < 0)\n $popin['$forms'].push(_id);\n\n $forms[i].close = popinClose;\n $validatorInstance.isPopinContext = true;\n $validatorInstance.validateFormById($forms[i].getAttribute('id')); //$forms[i]['id']\n\n removeListener(gina, $popin.target, eventType);\n }\n }\n \n }\n \n function updateToolbar(result, resultIsObject) {\n // update toolbar errors\n var $popin = getActivePopin();\n \n if ( gina && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar && typeof(result) != 'undefined' && typeof(resultIsObject) != 'undefined' && result ) {\n \n var XHRData = result;\n \n try { \n var XHRDataNew = null;\n if ( !resultIsObject && XHRData.error && /^(\\{|\\[)/.test(XHRData.error) )\n XHRData.error = JSON.parse(XHRData.error);\n \n // bad .. should not happen\n if ( typeof(XHRData.error) != 'undefined' && typeof(XHRData.error) == 'object' && typeof(XHRData.error) == 'object' ) {\n // by default\n XHRDataNew = { 'status' : XHRData.status };\n // existing will be overriden by user\n for (xErr in XHRData.error) {\n if ( !/^error$/.test(xErr ) ) {\n XHRDataNew[xErr] = XHRData.error[xErr];\n }\n }\n\n XHRDataNew.error = XHRData.error.error;\n\n XHRData = result = XHRDataNew\n } else if ( typeof(XHRData.error) != 'undefined' && typeof(XHRData.error) == 'string' ) {\n XHRData = result;\n }\n \n XHRData.isXHRViewData = true;\n ginaToolbar.update('data-xhr', XHRData );\n return;\n } catch (err) {\n throw err\n }\n }\n \n // update toolbar\n try {\n var $popin = getPopinById(instance.activePopinId);\n var $el = $popin.target;\n } catch (err) {\n ginaToolbar.update('data-xhr', err );\n }\n \n \n // XHRData\n var XHRData = null; \n if ( typeof(result) == 'string' && /\\<(.*)\\>/.test(result) ) {\n // converting Element to DOM object\n XHRData = new DOMParser().parseFromString(result, 'text/html').getElementById('gina-without-layout-xhr-data'); \n } else {\n XHRData = document.getElementById('gina-without-layout-xhr-data');\n }\n \n if ( gina && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar && XHRData ) {\n try {\n\n if ( typeof(XHRData.value) != 'undefined' && XHRData.value ) {\n XHRData = JSON.parse( decodeURIComponent( XHRData.value ) );\n // reset data-xhr\n XHRData.isXHRViewData = true;\n ginaToolbar.update('data-xhr', XHRData);\n }\n\n } catch (err) {\n throw err\n }\n }\n\n // XHRView\n var XHRView = null;\n if ( typeof(result) == 'string' && /\\<(.*)\\>/.test(result) ) { \n // converting Element to DOM object\n XHRView = new DOMParser().parseFromString(result, 'text/html').getElementById('gina-without-layout-xhr-view'); \n } else {\n XHRView = document.getElementById('gina-without-layout-xhr-view');\n }\n \n if ( gina && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar && XHRView ) {\n try {\n\n if ( typeof(XHRView.value) != 'undefined' && XHRView.value ) {\n \n XHRView = JSON.parse( decodeURIComponent( XHRView.value ) ); \n // reset data-xhr\n //ginaToolbar.update(\"view-xhr\", null);\n ginaToolbar.update('view-xhr', XHRView);\n }\n\n // popin content\n ginaToolbar.update('el-xhr', $popin.id);\n\n } catch (err) {\n throw err\n }\n }\n }\n\n\n\n /**\n * XML Request options\n * */\n var xhrOptions = {\n 'url' : '',\n 'method' : 'GET',\n 'isSynchrone' : false,\n 'withCredentials': true, // if should be enabled under a trusted env\n 'headers' : {\n // cross domain is enabled by default, but you need to setup `Access-Control-Allow-Origin`\n 'X-Requested-With': 'XMLHttpRequest' // to set isXMLRequest == true && in case of cross domain origin\n\n }\n };\n\n /**\n * popinLoad\n *\n * @param {string} name\n * @param {string} url\n * @param {object} [options]\n * */\n function popinLoad(name, url, options) {\n // if no name defiend, get the current\n if ( typeof(name) == 'undefined' ) {\n if ( typeof(this.name) == 'undefined' ) {\n throw new Error('`$popin.name` needs to be defined !')\n }\n name = this.name;\n } else if (typeof(this.name) == 'undefined' && name != 'undefined') {\n this.name = name;\n }\n // popin object\n var $popin = getPopinByName(name);\n var id = $popin.id;\n \n // set as active if none is active\n if ( !gina.popin.activePopinId ) {\n gina.popin.activePopinId = id;\n }\n \n // popin element\n var $el = document.getElementById(id) || null;\n\n if ( $el == null ) {\n\n var className = $popin.options.class +' '+ id;\n $el = document.createElement('div');\n $el.setAttribute('id', id);\n $el.setAttribute('class', className);\n instance.target.firstChild.appendChild($el);\n }\n\n if ( typeof(options) == 'undefined' ) {\n options = xhrOptions;\n } else {\n // In order to inherit without overriding default xhrOptions\n var isWithCredentials = xhrOptions.withCredentials;\n options = merge(options, xhrOptions);\n \n options.withCredentials = isWithCredentials;\n }\n \n if ( \n /^(http|https)\\:/.test(url)\n && !new RegExp('^' + window.location.protocol + '//'+ window.location.host).test(url) \n ) {\n // is request from same domain ?\n //options.headers['Origin'] = window.protocol+'//'+window.location.host;\n //options.headers['Origin'] = '*';\n //options.headers['Host'] = 'https://domain.local:3154';\n var isSameDomain = ( new RegExp(window.location.hostname).test(url) ) ? true : false;\n if (!isSameDomain) {\n // proxy external urls\n // TODO - instead of using `cors.io` or similar services, try to intégrate a local CORS proxy similar to : http://oskarhane.com/avoid-cors-with-nginx-proxy_pass/\n //url = url.match(/^(https|http)\\:/)[0] + '//cors.io/?' + url;\n url = url.match(/^(https|http)\\:/)[0] + '//corsacme.herokuapp.com/?'+ url;\n //url = url.match(/^(https|http)\\:/)[0] + '//cors-anywhere.herokuapp.com/' + url;\n \n //delete options.headers['X-Requested-With']\n \n // remove credentials on untrusted env\n // if forced by user options, it will be restored with $popin.options merge\n options.withCredentials = false;\n }\n }\n options.url = url;\n // updating popin options\n $popin.options = merge(options, $popin.options);\n\n\n if ( options.withCredentials ) { // Preflighted requests \n if ('withCredentials' in xhr) {\n // XHR for Chrome/Firefox/Opera/Safari.\n if (options.isSynchrone) {\n xhr.open(options.method, options.url, options.isSynchrone)\n } else {\n xhr.open(options.method, options.url)\n }\n } else if ( typeof XDomainRequest != 'undefined' ) {\n // XDomainRequest for IE.\n xhr = new XDomainRequest();\n xhr.open(options.method, options.url);\n } else {\n // CORS not supported.\n xhr = null;\n var result = 'CORS not supported: the server is missing the header `\"Access-Control-Allow-Credentials\": true` ';\n triggerEvent(gina, $el, 'error.' + id, result)\n }\n } else { // simple requests\n \n if (options.isSynchrone) {\n xhr.open(options.method, options.url, options.isSynchrone)\n } else {\n xhr.open(options.method, options.url)\n }\n }\n\n \n\n if (xhr) {\n // setting up headers\n xhr.withCredentials = ( typeof(options.withCredentials) != 'undefined' ) ? options.withCredentials : false;\n \n xhr.onerror = function(event, err) {\n \n var error = 'Transaction error: might be due to the server CORS settings.\\nPlease, check the console for more details.';\n var result = {\n 'status': xhr.status, //500,\n 'error' : error\n }; \n \n var resultIsObject = true;\n instance.eventData.error = result +'/n'+ err; \n updateToolbar(result, resultIsObject);\n triggerEvent(gina, $el, 'error.' + id, result)\n }\n \n \n for (var header in options.headers) {\n xhr.setRequestHeader(header, options.headers[header]);\n }\n \n \n // catching ready state cb\n xhr.onreadystatechange = function (event) {\n if (xhr.readyState == 4) {\n // 200, 201, 201' etc ...\n if( /^2/.test(xhr.status) ) {\n\n try {\n var result = xhr.responseText\n , contentType = xhr.getResponseHeader(\"Content-Type\")\n , isJsonContent = (/application\\/json/.test( contentType )) ? true : false\n , isRedirecting = true // by default\n ;\n if ( isJsonContent ) {\n result = JSON.parse(xhr.responseText);\n result.status = xhr.status;\n result.contentType = contentType;\n isRedirecting = false;\n }\n \n\n instance.eventData.success = result;\n \n if ( \n !isJsonContent && $popin.isOpen && !$popin.hasForm\n ||\n !isJsonContent && $popin.isOpen && isRedirecting\n ) { \n popinLoadContent(result, isRedirecting);\n } else {\n \n if ( \n isJsonContent && typeof(result.location) != 'undefined' \n ||\n isJsonContent && typeof(result.reload) != 'undefined'\n ) {\n var isXhrRedirect = false;\n if (\n typeof(result.isXhrRedirect) != 'undefined'\n && /^true$/i.test(result.isXhrRedirect)\n ) {\n isXhrRedirect = true;\n }\n if ( typeof(result.location) != 'undefined' && isXhrRedirect ) {\n \n if ( \n typeof(result.popin) != 'undefined' \n && typeof(result.popin.close) != 'undefined'\n ) {\n $popin.isRedirecting = false;\n $popin.close();\n \n var _reload = (result.popin.reload) ? result.popin.reload : false;\n if ( !result.popin.location && !result.popin.url) {\n delete result.popin;\n // only exception\n if (_reload) {\n result.popin = { reload: _reload };\n }\n } \n }\n \n var _target = '_self'; // by default\n if ( typeof(result.target) != 'undefined' ) {\n if ( /^(blank|self|parent|top)$/ ) {\n result.target = '_'+result.target;\n }\n _target = result.target\n }\n \n // special case of location without having the popin open\n // can occure while tunnelling\n if ( /^_self$/.test(_target) ) {\n var popinUrl = null;\n if ( typeof(result.popin) != 'undefined' ) {\n popinUrl = result.popin.location || result.popin.url;\n } else {\n popinUrl = result.location;\n }\n \n $popin\n .load( $popin.name, popinUrl, $popin.options );\n return setTimeout( function onPopinredirect($popin){\n if (!$popin.isOpen) {\n $popin.open();\n return;\n }\n }, 50, $popin);\n }\n \n \n window.open(result.location, _target);\n return;\n }\n \n if ( typeof(result.location) != 'undefined' ) {\n document.location = result.location;\n return;\n }\n \n if ( typeof(result.reload) != 'undefined' ) {\n document.location.reload();\n return;\n }\n \n if ( typeof(result.popin) != 'undefined' ) {\n if ( typeof(result.popin.close) != 'undefined' ) {\n $popin.isRedirecting = false;\n popinClose($popin.name);\n }\n }\n }\n \n //if ( !isJsonContent && $popin.hasForm) {\n //$validatorInstance.handleXhrResponse(xhr, $forms[0], $forms[0].id, event, true);\n //handleXhr(xhr, $el, options, require)\n //return\n //}\n if ( !isJsonContent ) {\n triggerEvent(gina, $el, 'loaded.' + id, result);\n return\n }\n \n triggerEvent(gina, $forms[0], 'success.' + id, result);\n \n }\n \n if (GINA_ENV_IS_DEV)\n updateToolbar(result);\n\n } catch (err) {\n \n var resultIsObject = false;\n \n var result = {\n 'status': 422,\n 'error' : err.description || err.stack\n };\n \n if ( /application\\/json/.test( xhr.getResponseHeader(\"Content-Type\") ) ) {\n result.error = JSON.parse(xhr.responseText);\n resultIsObject = true\n }\n\n instance.eventData.error = result;\n if (GINA_ENV_IS_DEV)\n updateToolbar(result, resultIsObject);\n\n triggerEvent(gina, $el, 'error.' + id, result)\n }\n\n } else {\n //console.log('error event triggered ', event.target, $form);\n var resultIsObject = false;\n var result = {\n 'status': xhr.status,\n 'error' : xhr.responseText\n };\n\n if ( /application\\/json/.test( xhr.getResponseHeader(\"Content-Type\") ) ) {\n result.error = JSON.parse(xhr.responseText);\n resultIsObject = true\n }\n\n instance.eventData.error = result; \n \n\n // update toolbar\n if (GINA_ENV_IS_DEV)\n updateToolbar(result, resultIsObject);\n\n triggerEvent(gina, $el, 'error.' + id, result)\n }\n }\n };\n\n // catching request progress\n // xhr.onprogress = function(event) {\n // //console.log(\n // // 'progress position '+ event.position,\n // // '\\nprogress total size '+ event.totalSize\n // //);\n //\n // var percentComplete = (event.position / event.totalSize)*100;\n // var result = {\n // 'status': 100,\n // 'progress': percentComplete\n // };\n //\n // instance.eventData.onprogress = result;\n //\n // triggerEvent(gina, $el, 'progress.' + id, result)\n // };\n\n // catching timeout\n // xhr.ontimeout = function (event) {\n // var result = {\n // 'status': 408,\n // 'error': 'Request Timeout'\n // };\n //\n // instance.eventData.ontimeout = result;\n //\n // triggerEvent(gina, $el, 'error.' + id, result)\n // };\n\n\n // sending\n //var data = JSON.stringify({ sample: 'data'});\n xhr.send();\n \n\n return {\n 'open': function () {\n var fired = false;\n addListener(gina, $el, 'loaded.' + id, function(e) {\n \n e.preventDefault();\n\n if (!fired) {\n fired = true;\n \n instance.activePopinId = $popin.id;\n popinBind(e, $popin);\n popinOpen($popin.name);\n }\n });\n\n }\n }\n }\n\n }\n\n /**\n * popinLoadContent\n * \n * @param {string} html - plain/text\n * @param {boolean} [isRedirecting] - to handle link inside popin without form\n */\n function popinLoadContent(stringContent, isRedirecting) {\n \n var $popin = getActivePopin(); \n if ( !$popin ) { \n return;\n }\n if (!$popin.isOpen)\n throw new Error('Popin `'+$popin.name+'` is not open !');\n \n $popin.isRedirecting = ( typeof(isRedirecting) != 'undefined' ) ? isRedirecting : false;\n \n var $el = $popin.target;\n // if ( \n // typeof(stringContent) != 'undefined' \n // && typeof(stringContent.trim) == 'function' \n // ) {\n $el.innerHTML = stringContent.trim(); \n // }\n \n popinUnbind($popin.name, true); \n popinBind({ target: $el, type: 'loaded.' + $popin.id }, $popin);\n \n if ( !$popin.isRedirecting ) {\n triggerEvent(gina, instance.target, 'open.'+ $popin.id, $popin);\n } else {\n triggerEvent(gina, instance.target, 'loaded.' + $popin.id, $popin);\n }\n }\n \n function getScript(source) { \n // then trigger scripts load\n //var xhr = new XMLHttpRequest();\n var xhr = setupXhr();\n xhr.open('GET', source, true);\n xhr.setRequestHeader(\"Content-Type\", \"text/javascript\");\n xhr.onload = function () {\n eval(xhr.response);\n };\n xhr.send(); \n }\n \n /**\n * popinOpen\n * \n * If you get a x-origin error, check if you have `Vary` rule\n * set in your policy : // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary\n * \n * Add to your project/env.json the following rule\n * { \n * \"$bundle\" : {\n * \"server\": {\n * \"response\": {\n * // other definitions ...\n * \n * \"vary\": \"Origin\"\n * }\n * }\n * } \n * }\n * \n * Opens a popin by name\n *\n * @parama {string} name\n *\n * */\n function popinOpen(name) {\n\n var id = null, $el = null;\n var $popin = ( typeof(name) != 'undefined') ? getPopinByName(name) : getPopinById(this.id);\n if ( !$popin ) {\n throw new Error('Popin name `'+name+'` not found !')\n } \n id = $popin.id;\n $el = document.getElementById(id);\n \n // load external resources in order of declaration\n // TODO - Add support for stylesheets\n var globalScriptsList = $popin.parentScripts\n , scripts = $el.getElementsByTagName('script')\n //, globalStylesList = $popin.parentStyles\n , i = 0\n , len = scripts.length\n ;\n var domain = gina.config.hostname.replace(/(https|http|)\\:\\/\\//, '').replace(/\\:\\d+$/, '');\n var reDomain = new RegExp(domain+'\\:\\\\d+\\|'+domain); \n for (;i < len; ++i) {\n if ( typeof(scripts[i].src) == 'undefined' || scripts[i].src == '' ) {\n continue;\n }\n let filename = scripts[i].src\n .replace(/(https|http|)\\:\\/\\//, '')\n .replace(reDomain, '');\n // don't load if already in the global context\n if ( globalScriptsList.indexOf(filename) > -1 )\n continue;\n \n getScript(scripts[i].src);\n }\n //i = 0; len = styles.length\n \n popinBind({ target: $el, type: 'loaded.' + $popin.id }, $popin);\n \n\n if ( !/gina-popin-is-active/.test($el.className) )\n $el.className += ' gina-popin-is-active';\n\n // overlay\n if ( !/gina-popin-is-active/.test(instance.target.firstChild.className) )\n instance.target.firstChild.className += ' gina-popin-is-active'; \n // overlay\n if ( /gina-popin-is-active/.test(instance.target.firstChild.className) ) {\n removeListener(gina, instance.target, 'open.'+ $popin.id)\n }\n\n $popin.isOpen = true;\n // so it can be forwarded to the handler who is listening\n $popin.target = $el;\n \n instance.activePopinId = $popin.id;\n\n // update toolbar\n if (GINA_ENV_IS_DEV)\n updateToolbar();\n // var XHRData = document.getElementById('gina-without-layout-xhr-data');\n // if ( gina && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar && XHRData ) {\n // try {\n\n // if ( typeof(XHRData.value) != 'undefined' && XHRData.value ) {\n // XHRData = JSON.parse( decodeURIComponent( XHRData.value ) );\n // // reset data-xhr\n // ginaToolbar.update(\"data-xhr\", null);\n // XHRData.isXHRViewData = true;\n // ginaToolbar.update(\"data-xhr\", XHRData);\n // }\n\n // } catch (err) {\n // throw err\n // }\n // }\n\n // var XHRView = document.getElementById('gina-without-layout-xhr-view');\n // if ( gina && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar && XHRView ) {\n // try {\n\n // if ( typeof(XHRView.value) != 'undefined' && XHRView.value ) {\n // XHRView = JSON.parse( decodeURIComponent( XHRView.value ) );\n // // reset data-xhr\n // ginaToolbar.update(\"view-xhr\", null);\n\n // ginaToolbar.update(\"view-xhr\", XHRView);\n // }\n\n // // popin content\n // ginaToolbar.update(\"el-xhr\", id);\n\n // } catch (err) {\n // throw err\n // }\n // }\n\n triggerEvent(gina, instance.target, 'open.'+ $popin.id, $popin);\n }\n\n /**\n * popinUnbind\n *\n * Closes a popin by `name` or all `is-active`\n *\n * @parama {string} [name]\n *\n * */\n function popinUnbind(name, isRouting) {\n \n var $popin = ( typeof(name) != 'undefined') ? getPopinByName(name) : getActivePopin();\n var $el = null;\n if ( !$popin && typeof(name) != 'undefined' ) {\n throw new Error('Popin `'+name+'` not found !');\n }\n \n // by default\n if ( typeof($popin) != 'undefined' && $popin != null ) {\n $el = $popin.target;\n \n isRouting = ( typeof(isRouting) != 'undefined' ) ? isRouting : false;\n\n if ( $el != null && /gina-popin-is-active/.test($el.className) ) {\n if (!isRouting) {\n instance.target.firstChild.className = instance.target.firstChild.className.replace(/\\sgina-popin-is-active|gina-popin-is-active|gina-popin-is-active\\s/, '');\n $el.className = $el.className.replace(/\\sgina-popin-is-active|gina-popin-is-active|gina-popin-is-active\\s/, '');\n $el.innerHTML = '';\n } \n\n // removing from FormValidator instance\n if ($validatorInstance) {\n var i = 0, formsLength = $popin['$forms'].length;\n if ($validatorInstance['$forms'] && formsLength > 0) {\n for (; i < formsLength; ++i) {\n if ( typeof($validatorInstance['$forms'][ $popin['$forms'][i] ]) != 'undefined' )\n $validatorInstance['$forms'][ $popin['$forms'][i] ].destroy();\n\n $popin['$forms'].splice( i, 1);\n }\n }\n }\n \n gina.popinIsBinded = false;\n \n // remove listeners\n removeListener(gina, $popin.target, 'loaded.' + $popin.id);\n }\n } \n }\n \n\n /**\n * popinClose\n *\n * Closes a popin by `name` or all `is-active`\n *\n * @parama {string} [name]\n *\n * */\n function popinClose(name) {\n \n var $popin = null;\n if ( typeof(name) == 'undefined' && /^true$/.test(this.isOpen) ) {\n name = this.name;\n $popin = this;\n } else {\n $popin = getPopinByName(name) || getActivePopin();\n if (!$popin)\n return;\n \n name = $popin.name;\n }\n //var $popin = ( typeof(name) != 'undefined') ? getPopinByName(name) : getActivePopin();\n var $el = null;\n if ( !$popin && typeof(name) != 'undefined' ) {\n throw new Error('Popin `'+name+'` not found !');\n }\n if (!$popin.isOpen)\n return;\n \n // by default\n if ( typeof($popin) != 'undefined' && $popin != null ) {\n \n // in case popinClose is called by the user e.g.: binding cancel/close with a <A> tag\n // but at the same time, the <A> href is not empty -> redirection wanted in the HTML\n // in this case, we want to ignore close\n if ( $popin.isRedirecting )\n return;\n \n $el = $popin.target;\n \n removeListener(gina, $popin.target, 'ready.' + instance.id);\n \n if ( $popin.hasForm ) {\n $popin.hasForm = false;\n }\n\n if ( $el != null && /gina-popin-is-active/.test($el.className) ) {\n \n popinUnbind(name); \n $popin.isOpen = false;\n gina.popinIsBinded = false; \n\n // restore toolbar\n if ( GINA_ENV_IS_DEV && gina && typeof(window.ginaToolbar) != 'undefined' && window.ginaToolbar )\n ginaToolbar.restore();\n\n instance.activePopinId = null;\n if ( $popin.$headers.length > 0) {\n var s = 0\n , sLen = $popin.$headers.length\n ;\n try {\n for (; s<sLen; ++s) {\n document.getElementById( $popin.$headers[s].id ).remove(); \n }\n } catch(err){\n console.warn('Could not remove script `'+ $popin.$headers[s].id +'`\\n'+ err.stack)\n }\n $popin.$headers = []; \n }\n triggerEvent(gina, $popin.target, 'close.'+ $popin.id, $popin);\n }\n } \n }\n\n /**\n * popinDestroy\n *\n * Destroyes a popin by name\n *\n * @parama {string} name\n *\n * */\n function popinDestroy(name) {\n \n var $popin = ( typeof(name) != 'undefined') ? getPopinByName(name) : getActivePopin();\n var id = null, $el = null;\n if ( !$popin && typeof(name) != 'undefined' ) {\n throw new Error('Popin `'+name+'` not found !');\n }\n \n id = $popin.id;\n }\n \n function registerPopin($popin, options) {\n \n if ( typeof(options) != 'object' ) {\n throw new Error('`options` must be an object')\n }\n \n $popin.options = merge(options, self.options);\n $popin.id = 'gina-popin-' + instance.id +'-'+ $popin.options['name'];\n \n if ( typeof(instance.$popins[$popin.id]) == 'undefined' ) { \n\n if ( typeof($popin.options['name']) != 'string' || $popin.options['name'] == '' ) {\n throw new Error('`options.name` can not be left `empty` or `undefined`')\n }\n\n if ( registeredPopins.indexOf($popin.options['name']) > -1 ) {\n throw new Error('`popin '+$popin.options['name']+'` already exists !')\n }\n\n // import over plugins\n if ( typeof($popin.options['validator']) != 'undefined' ) {\n $validatorInstance = $popin.options['validator'];\n $popin.validateFormById = $validatorInstance.validateFormById;\n }\n \n\n $popin.options['class'] = 'gina-popin-container ' + $popin.options['class'];\n\n \n $popin.name = $popin.options['name']; \n $popin.target = instance.target; \n $popin.load = popinLoad;\n $popin.loadContent = popinLoadContent;\n $popin.open = popinOpen;\n $popin.close = popinClose;\n if (GINA_ENV_IS_DEV)\n $popin.updateToolbar = updateToolbar;\n \n // Get main resources\n $popin.parentScripts = [];\n $popin.parentStyles = [];\n var domain = gina.config.hostname.replace(/(https|http|)\\:\\/\\//, '').replace(/\\:\\d+$/, '');\n var reDomain = new RegExp(domain+'\\:\\\\d+\\|'+domain);\n // Parent scripts\n var mainDocumentScripts = document.getElementsByTagName('script');\n for (let s = 0, len = mainDocumentScripts.length; s < len; s++ ) {\n if (!mainDocumentScripts[s].src || mainDocumentScripts[s].src == '')\n continue;\n // Filename without domain\n let filename = mainDocumentScripts[s].src\n .replace(/(https|http|)\\:\\/\\//, '')\n .replace(reDomain, '');\n $popin.parentScripts[s] = filename;\n }\n // Parent Styles\n var mainDocumentStyles = document.getElementsByTagName('link'); \n for (let s = 0, len = mainDocumentStyles.length; s < len; s++ ) {\n if ( typeof(mainDocumentStyles[s].rel) == 'undefined' || !/stylesheet/i.test(mainDocumentStyles[s].rel) )\n continue;\n // Filename without domain\n let filename = mainDocumentStyles[s].href\n .replace(/(https|http|)\\:\\/\\//, '')\n .replace(reDomain, '');\n $popin.parentStyles[s] = filename;\n }\n \n \n \n instance.$popins[$popin.id] = $popin;\n\n // setting up AJAX\n if (window.XMLHttpRequest) { // Mozilla, Safari, ...\n xhr = new XMLHttpRequest();\n } else if (window.ActiveXObject) { // IE\n try {\n xhr = new ActiveXObject(\"Msxml2.XMLHTTP\");\n } catch (e) {\n try {\n xhr = new ActiveXObject(\"Microsoft.XMLHTTP\");\n }\n catch (e) {}\n }\n }\n \n \n \n bindOpen($popin); \n }\n }\n\n var init = function(options) {\n \n setupInstanceProto();\n //instance.on('init', function(event) {\n addListener(gina, instance.target, 'init.'+instance.id, function(e) {\n \n var $newPopin = null;\n var popinId = 'gina-popin-' + instance.id +'-'+ options['name'];\n if ( typeof(instance.$popins[popinId]) == 'undefined' ) { \n var $newPopin = merge({}, $popin); \n registerPopin($newPopin, options);\n }\n\n instance.isReady = true;\n gina.hasPopinHandler = true;\n gina.popin = merge(gina.popin, instance);\n // trigger popin ready event\n triggerEvent(gina, instance.target, 'ready.' + instance.id, $newPopin);\n });\n\n \n \n\n instance.initialized = true;\n\n return instance\n }\n \n var setupInstanceProto = function() {\n instance.getPopinById = getPopinById;\n instance.getPopinByName = getPopinByName;\n instance.load = popinLoad;\n instance.loadContent = popinLoadContent;\n instance.getActivePopin = getActivePopin;\n instance.open = popinOpen;\n instance.close = popinClose;\n }\n \n\n if ( !gina.hasPopinHandler ) {\n popinCreateContainer();\n } else {\n popinGetContainer()\n }\n\n return init(options)\n };\n\n return Popin\n});\n",
|
|
51
|
-
"/**\n * Operations on element\n * - animations\n * */\nfunction fadeIn(element) {\n var op = 0.1; // initial opacity\n element.style.display = 'block';\n var timer = setInterval(function () {\n if (op >= 1){\n clearInterval(timer);\n }\n element.style.opacity = op;\n element.style.filter = 'alpha(opacity=' + op * 100 + \")\";\n op += op * 0.1;\n }, 10);\n}\n\nfunction fadeOut(element) {\n var op = 1; // initial opacity\n var timer = setInterval(function () {\n if (op <= 0.1){\n clearInterval(timer);\n element.style.display = 'none';\n }\n element.style.opacity = op;\n element.style.filter = 'alpha(opacity=' + op * 100 + \")\";\n op -= op * 0.1;\n }, 50);\n}\n;\ndefine(\"utils/effects\", function(){});\n\n",
|
|
52
|
-
"/**\n * Object.assign\n * Ref.: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n * \n */\nif (typeof Object.assign !== 'function') {\n // Must be writable: true, enumerable: false, configurable: true\n Object.defineProperty(Object, \"assign\", {\n value: function assign(target, varArgs) { // .length of function is 2\n 'use strict';\n if (target === null || target === undefined) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n var to = Object(target);\n for (var index = 1; index < arguments.length; index++) {\n var nextSource = arguments[index];\n\n if (nextSource !== null && nextSource !== undefined) {\n for (var nextKey in nextSource) {\n // Avoid bugs when hasOwnProperty is shadowed\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n },\n writable: true,\n configurable: true\n });\n}\n \nif ( typeof(JSON.clone) == 'undefined' ) {\n /**\n * JSON.clone\n * Clone JSON object\n * \n * Changes made here must be reflected in: \n * - gina/utils/prototypes.js\n * - gina/framework/version/helpers/prototypes.js\n * - gina/framework/version/core/asset/js/plugin/src/gina/utils/polyfill.js\n * \n * @param {object} source\n * @param {object} [target]\n * \n * @returns {object} cloned JSON object\n **/\n var clone = function(source, target) {\n if (source == null || typeof source != 'object') return source;\n if (source.constructor != Object && source.constructor != Array) return source;\n if (source.constructor == Date || source.constructor == RegExp || source.constructor == Function ||\n source.constructor == String || source.constructor == Number || source.constructor == Boolean)\n return new source.constructor(source);\n\n target = target || new source.constructor();\n var i = 0\n , len = Object.getOwnPropertyNames(source).length || 0\n , keys = Object.keys(source)\n ;\n \n while (i<len) {\n target[keys[i]] = (typeof target[keys[i]] == 'undefined') ? clone(source[keys[i]], null) : target[keys[i]];\n i++;\n }\n i = null; len = null; keys = null;\n\n return target;\n };\n \n JSON.clone = clone;\n // WHY NOT USE SOMETHING ELSE ?\n // Could have been fine, but not working when you have references pointg to another object\n // return Object.assign({}, source); \n \n // Performences issue\n //return JSON.parse(JSON.stringify(source));\n}\n\nif ( typeof(JSON.escape) == 'undefined' ) {\n /**\n * JSON.escape\n * Escape special characters\n * \n * Changes made here must be reflected in: \n * - gina/utils/prototypes.js\n * - gina/framework/version/helpers/prototypes.js\n * - gina/framework/version/core/asset/js/plugin/src/gina/utils/polyfill.js\n * \n * @param {object} jsonStr\n * \n * @returns {object} escaped JSON string\n **/\n var escape = function(jsonStr){\n try {\n return jsonStr\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\")\n ;\n } catch (err) { \n throw err;\n }\n };\n \n JSON.escape = escape;\n};\ndefine(\"utils/polyfill\", function(){});\n\n",
|
|
53
|
-
"'use strict';\n/**\n * This file is part of the gina package.\n * Copyright (c) 2009-2022 Rhinostone <contact@gina.io>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n/**\n * @class Inherits\n *\n * @package gina.utils\n * @namesame gina.utils.inherits\n * @author Rhinostone <contact@gina.io>\n *\n * @api Public\n * */\nfunction Inherits(a, b) {\n\n /**\n * init\n * @constructor\n * */\n var init = function(a, b) {\n var err = check(a, b);\n\n if (!err) {\n\n var z = (function() {\n var _inherited = false, cache = a;\n\n if (!_inherited) {\n _inherited = true;\n\n return function() {\n\n if (this) {\n this.prototype = cache.prototype;\n\n if (!this.name) this.name = cache.name;\n\n this.prototype.name = this.name;\n\n //makes it compatible with node.js classes like EventEmitter\n for (var prop in b.prototype) {\n if (!this[prop]) {\n this[prop] = b.prototype[prop];\n }\n }\n\n b.apply(this, arguments);\n cache.apply(this, arguments);\n }\n };\n }\n\n }(a, b));\n\n //makes it compatible with node.js classes like EventEmitter\n if (a.prototype == undefined) {\n a.prototype = {};\n }\n\n if (b.prototype == undefined) {\n b.prototype = {};\n }\n\n a.prototype = Object.create(b.prototype, {});\n z.prototype = Object.create(a.prototype, {}); //{ name: { writable: true, configurable: true, value: name }\n\n return z;\n } else {\n throw new Error(err);\n }\n };\n\n var check = function(a, b) {\n if ( typeof(a) == 'undefined' || typeof(b) == 'undefined') {\n return 'inherits(a, b): neither [ a ] nor [ b ] can\\'t be undefined or null'\n }\n return false;\n };\n\n return init;\n}\n\n\nif ( ( typeof(module) !== 'undefined' ) && module.exports ) {\n // Publish as node.js module\n module.exports = Inherits();\n} else if ( typeof(define) === 'function' && define.amd) {\n // Publish as AMD module\n define( 'utils/inherits',[],function() { return Inherits(); });\n};\n",
|
|
54
|
-
"/**\n * Gina Frontend Framework\n *\n * Usage:\n * By adding gina tag in the end of the DOM ( just before </body>)\n *\n * <script type=\"text/javascript\" src=\"/js/vendor/gina/gina.min.js\"></script>\n *\n * You can add or edit config options through the `data-gina-config`\n * <script type=\"text/javascript\" src=\"/js/vendor/gina/gina.min.js\" data-gina-config=\"{ env: 'dev', envIsDev: true, webroot: '/' }\"></script>\n *\n * Through RequireJS\n *\n * var gina = require('gina');\n *\n * Useful Globals\n *\n * window['originalContext']\n * You have to passe your `jQuery` or your `DollarDom` context to Gina\n * e.g.: \n * window['originalContext'] = window['jQuery']\n * \n * This can be achieved by overriding `window['originalContext']` before defining your handler\n * Default value will be jQuery\n *\n * */\n\n//var wContext = ( typeof(window.onGinaLoaded) == 'undefined') ? window : parent.window; // iframe case\nvar readyList = [ { name: 'gina', ctx: window['gina'], fn: window.onGinaLoaded } ];\nvar readyFired = false;\nvar readyEventHandlersInstalled = false;\n\n// call this when the document is ready\n// this function protects itself against being called more than once\nfunction ready() {\n\n if (!readyFired) {\n // this must be set to true before we start calling callbacks\n readyFired = true;\n var result = null;\n var i = i || 0;\n\n var handleEvent = function (i, readyList) {\n\n if ( readyList[i] ) {\n\n if (readyList[i].name == 'gina') {\n\n var scheduler = window.setInterval(function (i, readyList) {\n try {\n if ( typeof(readyList) == 'undefined' ) {\n // Fixing init bug in chrome\n readyList = window.readyList;\n } \n readyList[i].ctx = window.gina;\n result = readyList[i].fn.call(window, readyList[i].ctx, window.require);\n\n // clear\n if (result) {\n window.clearInterval(scheduler);\n ++i;\n handleEvent(i, readyList);\n }\n } catch (err) {\n window.clearInterval(scheduler);\n throw err;\n }\n\n }, 50, i, readyList);\n\n\n } else { // onEachHandlerReady\n // iframe case\n if ( !window.$ && typeof(parent.window.$) != 'undefined' ) {\n window.$ = parent.window.$;\n }\n // by default, but can be overriden in your handler (before the handler definition)\n if ( typeof(window.originalContext) == 'undefined' && typeof(window.$) != 'undefined' ) {\n window.originalContext = window.$\n }\n readyList[i].ctx = window.originalContext || $;// passes the user's orignalContext by default; if no orignalContext is set will try users'jQuery\n readyList[i].fn.call(window, readyList[i].ctx, window.require);\n ++i;\n handleEvent(i, readyList);\n }\n\n } else { // end\n // allow any closures held by these functions to free\n readyList = [];\n }\n }\n\n handleEvent(i, readyList);\n }\n}\n\nfunction readyStateChange() {\n if ( document.readyState === 'complete' ) { \n gina.ready();\n }\n}\n\n\nif ( typeof(window['gina']) == 'undefined' ) {// could have be defined by loader\n\n var gina = {\n /**\n * `_global` is used mainly for google closure compilation in some cases\n * where eval() is called\n * It will store extenal variable definitions\n * e.g.: \n * root -> window.root\n * then you need to call :\n * gina._global.register({'root': yourValue });\n * => `window.root`now accessible\n * before using:\n * eval(root +'=value');\n * \n * when not required anymore\n * gina._global.unregister(['root])\n */\n /**@js_externs _global*/\n _global: {\n \n /**@js_externs register*/\n register: function(variables) {\n if ( typeof(variables) != 'undefined') {\n for (let k in variables) { \n // if ( typeof(window[k]) != 'undefined' ) {\n // // already register\n // continue;\n // //throw new Error('Gina cannot register _global.'+k+': variable name need to be changed, or you need to called `_global.unregister(['+k+'])` in order to use it');\n // }\n //window.gina['_global'][k] = variables[k]; \n window[k] = variables[k];\n }\n }\n },\n /**@js_externs unregister*/\n unregister: function(variables) {\n if ( typeof(variables) == 'undefined' || !Array.isArray(variables)) {\n throw new Error('`variables` needs to ba an array')\n }\n \n for (let i = 0, len = variables.length; i < len; i++) {\n //delete window.gina['_global'][ variables[i] ];\n //if ( typeof(window[ variables[i] ]) != 'undefined' ) {\n //console.debug('now removing: '+ variables[i]);\n delete window[ variables[i] ]\n //}\n }\n }\n },\n /**\n * ready\n * This is the one public interface use to wrap `handlers`\n * It is an equivalent of jQuery(document).ready(cb)\n *\n * No need to use it for `handlers`, it is automatically applied for each `handler`\n *\n * @callback {callback} callback\n * @param {object} [context] - if present, it will be passed\n * */\n /**@js_externs ready*/\n ready: function(callback, context) {\n\n\n // if ready has already fired, then just schedule the callback\n // to fire asynchronously, but right away\n if (readyFired) {\n setTimeout(function() {callback(context);}, 1);\n return;\n } else {\n // add the function and context to the list\n readyList.push({ name: 'anonymous', fn: callback, ctx: context });\n }\n\n // if document already ready to go, schedule the ready function to run\n // IE only safe when readyState is \"complete\", others safe when readyState is \"interactive\"\n if (document.readyState === \"complete\" || (!document.attachEvent && document.readyState === \"interactive\")) {\n setTimeout(ready, 1);\n } else if (!readyEventHandlersInstalled) {\n // otherwise if we don't have event handlers installed, install them\n if (document.addEventListener) {\n // first choice is DOMContentLoaded event\n document.addEventListener(\"DOMContentLoaded\", ready, false);\n // backup is window load event\n window.addEventListener(\"load\", ready, false);\n } else {\n // must be IE\n document.attachEvent(\"onreadystatechange\", readyStateChange);\n window.attachEvent(\"onload\", ready);\n }\n readyEventHandlersInstalled = true;\n }\n\n }\n };\n\n window['gina'] = gina;\n}\n\n\ndefine('core', ['require', 'gina'], function (require) {\n require('gina')(window['gina']); // passing core required lib through parameters\n});\n\n\nrequire.config({\n \"packages\": [\"gina\"]\n});\n\n// exporting\nrequire([\n //vendors\n \"vendor/uuid\",\n \"vendor/engine.io\",\n\n \"core\",\n // helpers\n \"helpers/prototypes\",\n \"helpers/binding\",\n \"helpers/dateFormat\",\n\n // plugins\n \"gina/link\",\n \"gina/validator\",\n \"gina/popin\",\n \"gina/storage\",\n\n // utils\n \"utils/dom\",\n \"utils/events\",\n \"utils/effects\",\n \"utils/polyfill\",\n \"utils/inherits\",\n //\"utils/merge\",\n \"utils/form-validator\",\n \"utils/collection\",\n \"utils/routing\"\n]);\n\n\n// catching freelancer script load event\nvar tags = document.getElementsByTagName('script');\n\nfor (var t = 0, len = tags.length; t < len; ++t) {\n\n if ( /gina.min.js|gina.js/.test( tags[t].getAttribute('src') ) ) {\n\n tags[t]['onload'] = function onGinaLoaded(e) {\n // TODO - get the version number from the response ?? console.log('tag ', tags[t].getAttribute('data-gina-config'));\n // var req = new XMLHttpRequest();\n // req.open('GET', document.location, false);\n // req.send(null);\n // var version = req.getAllResponseHeaders().match(/X-Powered-By:(.*)/)[0].replace('X-Powered-By: ', '');\n if (window['onGinaLoaded']) {\n var onGinaLoaded = window['onGinaLoaded']\n } else {\n function onGinaLoaded(gina) {\n\n if (!gina) {\n return false\n } else {\n if ( gina[\"isFrameworkLoaded\"] ) {\n return true\n }\n\n var options = gina['config'] = {\n /**@js_externs env*/\n //env : '{{ page.environment.env }}',\n /**@js_externs envIsDev*/\n envIsDev : ( /^true$/.test('{{ page.environment.envIsDev }}') ) ? true : false,\n /**@js_externs version*/\n //version : '{{ page.environment.version }}',\n /**@js_externs webroot*/\n 'webroot' : '{{ page.environment.webroot }}',\n };\n\n \n // globals\n window['GINA_ENV'] = '{{ GINA_ENV }}';\n window['GINA_ENV_IS_DEV'] = /^true$/i.test('{{ GINA_ENV_IS_DEV }}') ? true : false;\n if ( typeof(location.search) != 'undefined' && /debug\\=/i.test(window.location.search) ) {\n window['GINA_ENV_IS_DEV'] = gina['config']['envIsDev'] = options['envIsDev'] = /^true$/i.test(window.location.search.match(/debug=(true|false)/)[0].split(/\\=/)[1]) ? true: false; \n }\n\n gina[\"setOptions\"](options);\n gina[\"isFrameworkLoaded\"] = true;\n\n // making adding css to the head\n var link = null;\n link = document.createElement('link');\n link.href = options.webroot + \"css/vendor/gina/gina.min.css\";\n link.media = \"screen\";\n link.rel = \"stylesheet\";\n link.type = \"text/css\";\n document.getElementsByTagName('head')[0].appendChild(link);\n\n return true\n }\n }\n }\n\n\n if (document.addEventListener) {\n document.addEventListener(\"ginaloaded\", function(event){\n //console.log('Gina Framework is ready !');\n window['gina'] = event.detail;\n onGinaLoaded(event.detail)\n })\n } else if (document.attachEvent) {\n document.attachEvent(\"ginaloaded\", function(event){\n window['gina'] = event.detail;\n onGinaLoaded(event.detail)\n })\n }\n }()\n break;\n }\n};\n"
|
|
55
|
-
]
|
|
56
|
-
}
|